]>
Commit | Line | Data |
---|---|---|
a22099f5 EN |
1 | #!/bin/sh |
2 | ||
3 | test_description="remember regular & dir renames in sequence of merges" | |
4 | ||
5 | . ./test-lib.sh | |
6 | ||
7 | # | |
8 | # NOTE 1: this testfile tends to not only rename files, but modify on both | |
9 | # sides; without modifying on both sides, optimizations can kick in | |
10 | # which make rename detection irrelevant or trivial. We want to make | |
11 | # sure that we are triggering rename caching rather than rename | |
12 | # bypassing. | |
13 | # | |
14 | # NOTE 2: this testfile uses 'test-tool fast-rebase' instead of either | |
15 | # cherry-pick or rebase. sequencer.c is only superficially | |
16 | # integrated with merge-ort; it calls merge_switch_to_result() | |
17 | # after EACH merge, which updates the index and working copy AND | |
18 | # throws away the cached results (because merge_switch_to_result() | |
19 | # is only supposed to be called at the end of the sequence). | |
20 | # Integrating them more deeply is a big task, so for now the tests | |
21 | # use 'test-tool fast-rebase'. | |
22 | # | |
23 | ||
24 | ||
25 | # | |
26 | # In the following simple testcase: | |
27 | # Base: numbers_1, values_1 | |
28 | # Upstream: numbers_2, values_2 | |
29 | # Topic_1: sequence_3 | |
30 | # Topic_2: scruples_3 | |
31 | # or, in english, rename numbers -> sequence in the first commit, and rename | |
32 | # values -> scruples in the second commit. | |
33 | # | |
34 | # This shouldn't be a challenge, it's just verifying that cached renames isn't | |
35 | # preventing us from finding new renames. | |
36 | # | |
37 | test_expect_success 'caching renames does not preclude finding new ones' ' | |
6693fb3f | 38 | git init caching-renames-and-new-renames && |
a22099f5 EN |
39 | ( |
40 | cd caching-renames-and-new-renames && | |
41 | ||
42 | test_seq 2 10 >numbers && | |
43 | test_seq 2 10 >values && | |
44 | git add numbers values && | |
45 | git commit -m orig && | |
46 | ||
47 | git branch upstream && | |
48 | git branch topic && | |
49 | ||
50 | git switch upstream && | |
51 | test_seq 1 10 >numbers && | |
52 | test_seq 1 10 >values && | |
53 | git add numbers values && | |
54 | git commit -m "Tweaked both files" && | |
55 | ||
56 | git switch topic && | |
57 | ||
58 | test_seq 2 12 >numbers && | |
59 | git add numbers && | |
60 | git mv numbers sequence && | |
61 | git commit -m A && | |
62 | ||
63 | test_seq 2 12 >values && | |
64 | git add values && | |
65 | git mv values scruples && | |
66 | git commit -m B && | |
67 | ||
68 | # | |
69 | # Actual testing | |
70 | # | |
71 | ||
72 | git switch upstream && | |
73 | ||
3916ec30 | 74 | git replay --onto HEAD upstream~1..topic >out && |
81613be3 EN |
75 | git update-ref --stdin <out && |
76 | git checkout topic && | |
a22099f5 EN |
77 | |
78 | git ls-files >tracked-files && | |
79 | test_line_count = 2 tracked-files && | |
80 | test_seq 1 12 >expect && | |
81 | test_cmp expect sequence && | |
82 | test_cmp expect scruples | |
83 | ) | |
84 | ' | |
85 | ||
86 | # | |
87 | # In the following testcase: | |
88 | # Base: numbers_1 | |
89 | # Upstream: rename numbers_1 -> sequence_2 | |
90 | # Topic_1: numbers_3 | |
91 | # Topic_2: numbers_1 | |
92 | # or, in english, the first commit on the topic branch modifies numbers by | |
93 | # shrinking it (dramatically) and the second commit on topic reverts its | |
94 | # parent. | |
95 | # | |
96 | # Can git apply both patches? | |
97 | # | |
98 | # Traditional cherry-pick/rebase will fail to apply the second commit, the | |
99 | # one that reverted its parent, because despite detecting the rename from | |
100 | # 'numbers' to 'sequence' for the first commit, it fails to detect that | |
101 | # rename when picking the second commit. That's "reasonable" given the | |
102 | # dramatic change in size of the file, but remembering the rename and | |
103 | # reusing it is reasonable too. | |
104 | # | |
25e65b6d EN |
105 | # We do test here that we expect rename detection to only be run once total |
106 | # (the topic side of history doesn't need renames, and with caching we | |
107 | # should be able to only run rename detection on the upstream side one | |
108 | # time.) | |
a22099f5 | 109 | test_expect_success 'cherry-pick both a commit and its immediate revert' ' |
6693fb3f | 110 | git init pick-commit-and-its-immediate-revert && |
a22099f5 EN |
111 | ( |
112 | cd pick-commit-and-its-immediate-revert && | |
113 | ||
114 | test_seq 11 30 >numbers && | |
115 | git add numbers && | |
116 | git commit -m orig && | |
117 | ||
118 | git branch upstream && | |
119 | git branch topic && | |
120 | ||
121 | git switch upstream && | |
122 | test_seq 1 30 >numbers && | |
123 | git add numbers && | |
124 | git mv numbers sequence && | |
125 | git commit -m "Renamed (and modified) numbers -> sequence" && | |
126 | ||
127 | git switch topic && | |
128 | ||
129 | test_seq 11 13 >numbers && | |
130 | git add numbers && | |
131 | git commit -m A && | |
132 | ||
133 | git revert HEAD && | |
134 | ||
135 | # | |
136 | # Actual testing | |
137 | # | |
138 | ||
139 | git switch upstream && | |
140 | ||
141 | GIT_TRACE2_PERF="$(pwd)/trace.output" && | |
142 | export GIT_TRACE2_PERF && | |
143 | ||
3916ec30 | 144 | git replay --onto HEAD upstream~1..topic >out && |
81613be3 EN |
145 | git update-ref --stdin <out && |
146 | git checkout topic && | |
a22099f5 EN |
147 | |
148 | grep region_enter.*diffcore_rename trace.output >calls && | |
25e65b6d | 149 | test_line_count = 1 calls |
a22099f5 EN |
150 | ) |
151 | ' | |
152 | ||
153 | # | |
154 | # In the following testcase: | |
155 | # Base: sequence_1 | |
156 | # Upstream: rename sequence_1 -> values_2 | |
157 | # Topic_1: rename sequence_1 -> values_3 | |
158 | # Topic_2: add unrelated sequence_4 | |
159 | # or, in english, both sides rename sequence -> values, and then the second | |
160 | # commit on the topic branch adds an unrelated file called sequence. | |
161 | # | |
162 | # This testcase presents no problems for git traditionally, but having both | |
163 | # sides do the same rename in effect "uses it up" and if it remains cached, | |
164 | # could cause a spurious rename/add conflict. | |
165 | # | |
166 | test_expect_success 'rename same file identically, then reintroduce it' ' | |
6693fb3f | 167 | git init rename-rename-1to1-then-add-old-filename && |
a22099f5 EN |
168 | ( |
169 | cd rename-rename-1to1-then-add-old-filename && | |
170 | ||
171 | test_seq 3 8 >sequence && | |
172 | git add sequence && | |
173 | git commit -m orig && | |
174 | ||
175 | git branch upstream && | |
176 | git branch topic && | |
177 | ||
178 | git switch upstream && | |
179 | test_seq 1 8 >sequence && | |
180 | git add sequence && | |
181 | git mv sequence values && | |
182 | git commit -m "Renamed (and modified) sequence -> values" && | |
183 | ||
184 | git switch topic && | |
185 | ||
186 | test_seq 3 10 >sequence && | |
187 | git add sequence && | |
188 | git mv sequence values && | |
189 | git commit -m A && | |
190 | ||
191 | test_write_lines A B C D E F G H I J >sequence && | |
192 | git add sequence && | |
193 | git commit -m B && | |
194 | ||
195 | # | |
196 | # Actual testing | |
197 | # | |
198 | ||
199 | git switch upstream && | |
200 | ||
201 | GIT_TRACE2_PERF="$(pwd)/trace.output" && | |
202 | export GIT_TRACE2_PERF && | |
203 | ||
3916ec30 | 204 | git replay --onto HEAD upstream~1..topic >out && |
81613be3 EN |
205 | git update-ref --stdin <out && |
206 | git checkout topic && | |
a22099f5 EN |
207 | |
208 | git ls-files >tracked && | |
209 | test_line_count = 2 tracked && | |
210 | test_path_is_file values && | |
211 | test_path_is_file sequence && | |
212 | ||
213 | grep region_enter.*diffcore_rename trace.output >calls && | |
214 | test_line_count = 2 calls | |
215 | ) | |
216 | ' | |
217 | ||
218 | # | |
219 | # In the following testcase: | |
220 | # Base: olddir/{valuesZ_1, valuesY_1, valuesX_1} | |
221 | # Upstream: rename olddir/valuesZ_1 -> dirA/valuesZ_2 | |
222 | # rename olddir/valuesY_1 -> dirA/valuesY_2 | |
223 | # rename olddir/valuesX_1 -> dirB/valuesX_2 | |
224 | # Topic_1: rename olddir/valuesZ_1 -> dirA/valuesZ_3 | |
225 | # rename olddir/valuesY_1 -> dirA/valuesY_3 | |
226 | # Topic_2: add olddir/newfile | |
227 | # Expected Pick1: dirA/{valuesZ, valuesY}, dirB/valuesX | |
228 | # Expected Pick2: dirA/{valuesZ, valuesY}, dirB/{valuesX, newfile} | |
229 | # | |
230 | # This testcase presents no problems for git traditionally, but having both | |
231 | # sides do the same renames in effect "use it up" but if the renames remain | |
232 | # cached, the directory rename could put newfile in the wrong directory. | |
233 | # | |
234 | test_expect_success 'rename same file identically, then add file to old dir' ' | |
6693fb3f | 235 | git init rename-rename-1to1-then-add-file-to-old-dir && |
a22099f5 EN |
236 | ( |
237 | cd rename-rename-1to1-then-add-file-to-old-dir && | |
238 | ||
239 | mkdir olddir/ && | |
240 | test_seq 3 8 >olddir/valuesZ && | |
241 | test_seq 3 8 >olddir/valuesY && | |
242 | test_seq 3 8 >olddir/valuesX && | |
243 | git add olddir && | |
244 | git commit -m orig && | |
245 | ||
246 | git branch upstream && | |
247 | git branch topic && | |
248 | ||
249 | git switch upstream && | |
250 | test_seq 1 8 >olddir/valuesZ && | |
251 | test_seq 1 8 >olddir/valuesY && | |
252 | test_seq 1 8 >olddir/valuesX && | |
253 | git add olddir && | |
254 | mkdir dirA && | |
255 | git mv olddir/valuesZ olddir/valuesY dirA && | |
256 | git mv olddir/ dirB/ && | |
257 | git commit -m "Renamed (and modified) values*" && | |
258 | ||
259 | git switch topic && | |
260 | ||
261 | test_seq 3 10 >olddir/valuesZ && | |
262 | test_seq 3 10 >olddir/valuesY && | |
263 | git add olddir && | |
264 | mkdir dirA && | |
265 | git mv olddir/valuesZ olddir/valuesY dirA && | |
266 | git commit -m A && | |
267 | ||
268 | >olddir/newfile && | |
269 | git add olddir/newfile && | |
270 | git commit -m B && | |
271 | ||
272 | # | |
273 | # Actual testing | |
274 | # | |
275 | ||
276 | git switch upstream && | |
277 | git config merge.directoryRenames true && | |
278 | ||
279 | GIT_TRACE2_PERF="$(pwd)/trace.output" && | |
280 | export GIT_TRACE2_PERF && | |
281 | ||
3916ec30 | 282 | git replay --onto HEAD upstream~1..topic >out && |
81613be3 EN |
283 | git update-ref --stdin <out && |
284 | git checkout topic && | |
a22099f5 EN |
285 | |
286 | git ls-files >tracked && | |
287 | test_line_count = 4 tracked && | |
288 | test_path_is_file dirA/valuesZ && | |
289 | test_path_is_file dirA/valuesY && | |
290 | test_path_is_file dirB/valuesX && | |
291 | test_path_is_file dirB/newfile && | |
292 | ||
293 | grep region_enter.*diffcore_rename trace.output >calls && | |
294 | test_line_count = 3 calls | |
295 | ) | |
296 | ' | |
297 | ||
298 | # | |
299 | # In the following testcase, upstream renames a directory, and the topic branch | |
300 | # first adds a file to the directory, then later renames the directory | |
301 | # differently: | |
302 | # Base: olddir/a | |
303 | # olddir/b | |
304 | # Upstream: rename olddir/ -> newdir/ | |
305 | # Topic_1: add olddir/newfile | |
306 | # Topic_2: rename olddir/ -> otherdir/ | |
307 | # | |
308 | # Here we are just concerned that cached renames might prevent us from seeing | |
309 | # the rename conflict, and we want to ensure that we do get a conflict. | |
310 | # | |
25e65b6d EN |
311 | # While at it, though, we do test that we only try to detect renames 2 |
312 | # times and not three. (The first merge needs to detect renames on the | |
313 | # upstream side. Traditionally, the second merge would need to detect | |
314 | # renames on both sides of history, but our caching of upstream renames | |
315 | # should avoid the need to re-detect upstream renames.) | |
a22099f5 EN |
316 | # |
317 | test_expect_success 'cached dir rename does not prevent noticing later conflict' ' | |
6693fb3f | 318 | git init dir-rename-cache-not-occluding-later-conflict && |
a22099f5 EN |
319 | ( |
320 | cd dir-rename-cache-not-occluding-later-conflict && | |
321 | ||
322 | mkdir olddir && | |
323 | test_seq 3 10 >olddir/a && | |
324 | test_seq 3 10 >olddir/b && | |
325 | git add olddir && | |
326 | git commit -m orig && | |
327 | ||
328 | git branch upstream && | |
329 | git branch topic && | |
330 | ||
331 | git switch upstream && | |
332 | test_seq 3 10 >olddir/a && | |
333 | test_seq 3 10 >olddir/b && | |
334 | git add olddir && | |
335 | git mv olddir newdir && | |
336 | git commit -m "Dir renamed" && | |
337 | ||
338 | git switch topic && | |
339 | ||
340 | >olddir/newfile && | |
341 | git add olddir/newfile && | |
342 | git commit -m A && | |
343 | ||
344 | test_seq 1 8 >olddir/a && | |
345 | test_seq 1 8 >olddir/b && | |
346 | git add olddir && | |
347 | git mv olddir otherdir && | |
348 | git commit -m B && | |
349 | ||
350 | # | |
351 | # Actual testing | |
352 | # | |
353 | ||
354 | git switch upstream && | |
355 | git config merge.directoryRenames true && | |
356 | ||
357 | GIT_TRACE2_PERF="$(pwd)/trace.output" && | |
358 | export GIT_TRACE2_PERF && | |
359 | ||
3916ec30 | 360 | test_must_fail git replay --onto HEAD upstream~1..topic >output && |
a22099f5 | 361 | |
a22099f5 | 362 | grep region_enter.*diffcore_rename trace.output >calls && |
25e65b6d | 363 | test_line_count = 2 calls |
a22099f5 EN |
364 | ) |
365 | ' | |
366 | ||
367 | # Helper for the next two tests | |
368 | test_setup_upstream_rename () { | |
6693fb3f | 369 | git init $1 && |
a22099f5 EN |
370 | ( |
371 | cd $1 && | |
372 | ||
373 | test_seq 3 8 >somefile && | |
374 | test_seq 3 8 >relevant-rename && | |
375 | git add somefile relevant-rename && | |
376 | mkdir olddir && | |
377 | test_write_lines a b c d e f g >olddir/a && | |
378 | test_write_lines z y x w v u t >olddir/b && | |
379 | git add olddir && | |
380 | git commit -m orig && | |
381 | ||
382 | git branch upstream && | |
383 | git branch topic && | |
384 | ||
385 | git switch upstream && | |
386 | test_seq 1 8 >somefile && | |
387 | test_seq 1 8 >relevant-rename && | |
388 | git add somefile relevant-rename && | |
389 | git mv relevant-rename renamed && | |
390 | echo h >>olddir/a && | |
391 | echo s >>olddir/b && | |
392 | git add olddir && | |
393 | git mv olddir newdir && | |
394 | git commit -m "Dir renamed" | |
395 | ) | |
396 | } | |
397 | ||
398 | # | |
399 | # In the following testcase, upstream renames a file in the toplevel directory | |
400 | # as well as its only directory: | |
401 | # Base: relevant-rename_1 | |
402 | # somefile | |
403 | # olddir/a | |
404 | # olddir/b | |
405 | # Upstream: rename relevant-rename_1 -> renamed_2 | |
406 | # rename olddir/ -> newdir/ | |
407 | # Topic_1: relevant-rename_3 | |
408 | # Topic_2: olddir/newfile_1 | |
409 | # Topic_3: olddir/newfile_2 | |
410 | # | |
411 | # In this testcase, since the first commit being picked only modifies a | |
412 | # file in the toplevel directory, the directory rename is irrelevant for | |
413 | # that first merge. However, we need to notice the directory rename for | |
414 | # the merge that picks the second commit, and we don't want the third | |
415 | # commit to mess up its location either. We want to make sure that | |
416 | # olddir/newfile doesn't exist in the result and that newdir/newfile does. | |
417 | # | |
25e65b6d EN |
418 | # We also test that we only do rename detection twice. We never need |
419 | # rename detection on the topic side of history, but we do need it twice on | |
420 | # the upstream side of history. For the first topic commit, we only need | |
421 | # the | |
422 | # relevant-rename -> renamed | |
423 | # rename, because olddir is unmodified by Topic_1. For Topic_2, however, | |
424 | # the new file being added to olddir means files that were previously | |
425 | # irrelevant for rename detection are now relevant, forcing us to repeat | |
426 | # rename detection for the paths we don't already have cached. Topic_3 also | |
427 | # tweaks olddir/newfile, but the renames in olddir/ will have been cached | |
428 | # from the second rename detection run. | |
a22099f5 EN |
429 | # |
430 | test_expect_success 'dir rename unneeded, then add new file to old dir' ' | |
431 | test_setup_upstream_rename dir-rename-unneeded-until-new-file && | |
432 | ( | |
433 | cd dir-rename-unneeded-until-new-file && | |
434 | ||
435 | git switch topic && | |
436 | ||
437 | test_seq 3 10 >relevant-rename && | |
438 | git add relevant-rename && | |
439 | git commit -m A && | |
440 | ||
441 | echo foo >olddir/newfile && | |
442 | git add olddir/newfile && | |
443 | git commit -m B && | |
444 | ||
445 | echo bar >>olddir/newfile && | |
446 | git add olddir/newfile && | |
447 | git commit -m C && | |
448 | ||
449 | # | |
450 | # Actual testing | |
451 | # | |
452 | ||
453 | git switch upstream && | |
454 | git config merge.directoryRenames true && | |
455 | ||
456 | GIT_TRACE2_PERF="$(pwd)/trace.output" && | |
457 | export GIT_TRACE2_PERF && | |
458 | ||
3916ec30 | 459 | git replay --onto HEAD upstream~1..topic >out && |
81613be3 EN |
460 | git update-ref --stdin <out && |
461 | git checkout topic && | |
a22099f5 EN |
462 | |
463 | grep region_enter.*diffcore_rename trace.output >calls && | |
25e65b6d | 464 | test_line_count = 2 calls && |
a22099f5 EN |
465 | |
466 | git ls-files >tracked && | |
467 | test_line_count = 5 tracked && | |
468 | test_path_is_missing olddir/newfile && | |
469 | test_path_is_file newdir/newfile | |
470 | ) | |
471 | ' | |
472 | ||
473 | # | |
474 | # The following testcase is *very* similar to the last one, but instead of | |
475 | # adding a new olddir/newfile, it renames somefile -> olddir/newfile: | |
476 | # Base: relevant-rename_1 | |
477 | # somefile_1 | |
478 | # olddir/a | |
479 | # olddir/b | |
480 | # Upstream: rename relevant-rename_1 -> renamed_2 | |
481 | # rename olddir/ -> newdir/ | |
482 | # Topic_1: relevant-rename_3 | |
483 | # Topic_2: rename somefile -> olddir/newfile_2 | |
484 | # Topic_3: modify olddir/newfile_3 | |
485 | # | |
486 | # In this testcase, since the first commit being picked only modifies a | |
487 | # file in the toplevel directory, the directory rename is irrelevant for | |
488 | # that first merge. However, we need to notice the directory rename for | |
489 | # the merge that picks the second commit, and we don't want the third | |
490 | # commit to mess up its location either. We want to make sure that | |
491 | # neither somefile or olddir/newfile exists in the result and that | |
492 | # newdir/newfile does. | |
493 | # | |
494 | # This testcase needs one more call to rename detection than the last | |
495 | # testcase, because of the somefile -> olddir/newfile rename in Topic_2. | |
496 | test_expect_success 'dir rename unneeded, then rename existing file into old dir' ' | |
497 | test_setup_upstream_rename dir-rename-unneeded-until-file-moved-inside && | |
498 | ( | |
499 | cd dir-rename-unneeded-until-file-moved-inside && | |
500 | ||
501 | git switch topic && | |
502 | ||
503 | test_seq 3 10 >relevant-rename && | |
504 | git add relevant-rename && | |
505 | git commit -m A && | |
506 | ||
507 | test_seq 1 10 >somefile && | |
508 | git add somefile && | |
509 | git mv somefile olddir/newfile && | |
510 | git commit -m B && | |
511 | ||
512 | test_seq 1 12 >olddir/newfile && | |
513 | git add olddir/newfile && | |
514 | git commit -m C && | |
515 | ||
516 | # | |
517 | # Actual testing | |
518 | # | |
519 | ||
520 | git switch upstream && | |
521 | git config merge.directoryRenames true && | |
522 | ||
523 | GIT_TRACE2_PERF="$(pwd)/trace.output" && | |
524 | export GIT_TRACE2_PERF && | |
525 | ||
3916ec30 | 526 | git replay --onto HEAD upstream~1..topic >out && |
81613be3 EN |
527 | git update-ref --stdin <out && |
528 | git checkout topic && | |
a22099f5 EN |
529 | |
530 | grep region_enter.*diffcore_rename trace.output >calls && | |
25e65b6d | 531 | test_line_count = 3 calls && |
a22099f5 EN |
532 | |
533 | test_path_is_missing somefile && | |
534 | test_path_is_missing olddir/newfile && | |
535 | test_path_is_file newdir/newfile && | |
536 | git ls-files >tracked && | |
537 | test_line_count = 4 tracked | |
538 | ) | |
539 | ' | |
540 | ||
541 | # Helper for the next two tests | |
542 | test_setup_topic_rename () { | |
6693fb3f | 543 | git init $1 && |
a22099f5 EN |
544 | ( |
545 | cd $1 && | |
546 | ||
547 | test_seq 3 8 >somefile && | |
548 | mkdir olddir && | |
549 | test_seq 3 8 >olddir/a && | |
550 | echo b >olddir/b && | |
551 | git add olddir somefile && | |
552 | git commit -m orig && | |
553 | ||
554 | git branch upstream && | |
555 | git branch topic && | |
556 | ||
557 | git switch topic && | |
558 | test_seq 1 8 >somefile && | |
559 | test_seq 1 8 >olddir/a && | |
560 | git add somefile olddir/a && | |
561 | git mv olddir newdir && | |
562 | git commit -m "Dir renamed" && | |
563 | ||
564 | test_seq 1 10 >somefile && | |
565 | git add somefile && | |
566 | mkdir olddir && | |
567 | >olddir/unrelated-file && | |
568 | git add olddir && | |
569 | git commit -m "Unrelated file in recreated old dir" | |
570 | ) | |
571 | } | |
572 | ||
573 | # | |
574 | # In the following testcase, the first commit on the topic branch renames | |
575 | # a directory, while the second recreates the old directory and places a | |
576 | # file into it: | |
577 | # Base: somefile | |
578 | # olddir/a | |
579 | # olddir/b | |
580 | # Upstream: olddir/newfile | |
581 | # Topic_1: somefile_2 | |
582 | # rename olddir/ -> newdir/ | |
583 | # Topic_2: olddir/unrelated-file | |
584 | # | |
585 | # Note that the first pick should merge: | |
586 | # Base: somefile | |
587 | # olddir/{a,b} | |
588 | # Upstream: olddir/newfile | |
589 | # Topic_1: rename olddir/ -> newdir/ | |
590 | # For which the expected result (assuming merge.directoryRenames=true) is | |
591 | # clearly: | |
592 | # Result: somefile | |
593 | # newdir/{a, b, newfile} | |
594 | # | |
595 | # While the second pick does the following three-way merge: | |
596 | # Base (Topic_1): somefile | |
597 | # newdir/{a,b} | |
598 | # Upstream (Result from 1): same files as base, but adds newdir/newfile | |
599 | # Topic_2: same files as base, but adds olddir/unrelated-file | |
600 | # | |
601 | # The second merge is pretty trivial; upstream adds newdir/newfile, and | |
602 | # topic_2 adds olddir/unrelated-file. We're just testing that we don't | |
603 | # accidentally cache directory renames somehow and rename | |
604 | # olddir/unrelated-file to newdir/unrelated-file. | |
605 | # | |
606 | # This testcase should only need one call to diffcore_rename_extended(). | |
607 | test_expect_success 'caching renames only on upstream side, part 1' ' | |
608 | test_setup_topic_rename cache-renames-only-upstream-add-file && | |
609 | ( | |
610 | cd cache-renames-only-upstream-add-file && | |
611 | ||
612 | git switch upstream && | |
613 | ||
614 | >olddir/newfile && | |
615 | git add olddir/newfile && | |
616 | git commit -m "Add newfile" && | |
617 | ||
618 | # | |
619 | # Actual testing | |
620 | # | |
621 | ||
622 | git switch upstream && | |
623 | ||
624 | git config merge.directoryRenames true && | |
625 | ||
626 | GIT_TRACE2_PERF="$(pwd)/trace.output" && | |
627 | export GIT_TRACE2_PERF && | |
628 | ||
3916ec30 | 629 | git replay --onto HEAD upstream~1..topic >out && |
81613be3 EN |
630 | git update-ref --stdin <out && |
631 | git checkout topic && | |
a22099f5 EN |
632 | |
633 | grep region_enter.*diffcore_rename trace.output >calls && | |
634 | test_line_count = 1 calls && | |
635 | ||
636 | git ls-files >tracked && | |
637 | test_line_count = 5 tracked && | |
638 | test_path_is_missing newdir/unrelated-file && | |
639 | test_path_is_file olddir/unrelated-file && | |
640 | test_path_is_file newdir/newfile && | |
641 | test_path_is_file newdir/b && | |
642 | test_path_is_file newdir/a && | |
643 | test_path_is_file somefile | |
644 | ) | |
645 | ' | |
646 | ||
647 | # | |
648 | # The following testcase is *very* similar to the last one, but instead of | |
649 | # adding a new olddir/newfile, it renames somefile -> olddir/newfile: | |
650 | # Base: somefile | |
651 | # olddir/a | |
652 | # olddir/b | |
653 | # Upstream: somefile_1 -> olddir/newfile | |
654 | # Topic_1: rename olddir/ -> newdir/ | |
655 | # somefile_2 | |
656 | # Topic_2: olddir/unrelated-file | |
657 | # somefile_3 | |
658 | # | |
659 | # Much like the previous test, this case is actually trivial and we are just | |
660 | # making sure there isn't some spurious directory rename caching going on | |
661 | # for the wrong side of history. | |
662 | # | |
663 | # | |
25e65b6d EN |
664 | # This testcase should only need two calls to diffcore_rename_extended(), |
665 | # both for the first merge, one for each side of history. | |
a22099f5 EN |
666 | # |
667 | test_expect_success 'caching renames only on upstream side, part 2' ' | |
668 | test_setup_topic_rename cache-renames-only-upstream-rename-file && | |
669 | ( | |
670 | cd cache-renames-only-upstream-rename-file && | |
671 | ||
672 | git switch upstream && | |
673 | ||
674 | git mv somefile olddir/newfile && | |
675 | git commit -m "Add newfile" && | |
676 | ||
677 | # | |
678 | # Actual testing | |
679 | # | |
680 | ||
681 | git switch upstream && | |
682 | ||
683 | git config merge.directoryRenames true && | |
684 | ||
685 | GIT_TRACE2_PERF="$(pwd)/trace.output" && | |
686 | export GIT_TRACE2_PERF && | |
687 | ||
3916ec30 | 688 | git replay --onto HEAD upstream~1..topic >out && |
81613be3 EN |
689 | git update-ref --stdin <out && |
690 | git checkout topic && | |
a22099f5 EN |
691 | |
692 | grep region_enter.*diffcore_rename trace.output >calls && | |
25e65b6d | 693 | test_line_count = 2 calls && |
a22099f5 EN |
694 | |
695 | git ls-files >tracked && | |
696 | test_line_count = 4 tracked && | |
697 | test_path_is_missing newdir/unrelated-file && | |
698 | test_path_is_file olddir/unrelated-file && | |
699 | test_path_is_file newdir/newfile && | |
700 | test_path_is_file newdir/b && | |
701 | test_path_is_file newdir/a | |
702 | ) | |
703 | ' | |
704 | ||
9ae39fef EN |
705 | # |
706 | # The following testcase just creates two simple renames (slightly modified | |
707 | # on both sides but without conflicting changes), and a directory full of | |
708 | # files that are otherwise uninteresting. The setup is as follows: | |
709 | # | |
710 | # base: unrelated/<BUNCH OF FILES> | |
711 | # numbers | |
712 | # values | |
713 | # upstream: modify: numbers | |
714 | # modify: values | |
715 | # topic: add: unrelated/foo | |
716 | # modify: numbers | |
717 | # modify: values | |
718 | # rename: numbers -> sequence | |
719 | # rename: values -> progression | |
720 | # | |
721 | # This is a trivial rename case, but we're curious what happens with a very | |
722 | # low renameLimit interacting with the restart optimization trying to notice | |
723 | # that unrelated/ looks like a trivial merge candidate. | |
724 | # | |
725 | test_expect_success 'avoid assuming we detected renames' ' | |
726 | git init redo-weirdness && | |
727 | ( | |
728 | cd redo-weirdness && | |
729 | ||
730 | mkdir unrelated && | |
731 | for i in $(test_seq 1 10) | |
732 | do | |
0e66bc1b | 733 | >unrelated/$i || exit 1 |
9ae39fef EN |
734 | done && |
735 | test_seq 2 10 >numbers && | |
736 | test_seq 12 20 >values && | |
737 | git add numbers values unrelated/ && | |
738 | git commit -m orig && | |
739 | ||
740 | git branch upstream && | |
741 | git branch topic && | |
742 | ||
743 | git switch upstream && | |
744 | test_seq 1 10 >numbers && | |
745 | test_seq 11 20 >values && | |
746 | git add numbers && | |
747 | git commit -m "Some tweaks" && | |
748 | ||
749 | git switch topic && | |
750 | ||
751 | >unrelated/foo && | |
752 | test_seq 2 12 >numbers && | |
753 | test_seq 12 22 >values && | |
754 | git add numbers values unrelated/ && | |
755 | git mv numbers sequence && | |
756 | git mv values progression && | |
757 | git commit -m A && | |
758 | ||
759 | # | |
760 | # Actual testing | |
761 | # | |
762 | ||
763 | git switch --detach topic^0 && | |
764 | ||
765 | test_must_fail git -c merge.renameLimit=1 rebase upstream && | |
766 | ||
767 | git ls-files -u >actual && | |
ec2f6c0c | 768 | test_line_count = 2 actual |
9ae39fef EN |
769 | ) |
770 | ' | |
771 | ||
a22099f5 | 772 | test_done |