1#!/bin/sh
2
3test_description='Merge-recursive merging renames'
4. ./test-lib.sh
5
6modify () {
7 sed -e "$1" <"$2" >"$2.x" &&
8 mv "$2.x" "$2"
9}
10
11test_expect_success setup \
12'
13cat >A <<\EOF &&
14a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
15b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
16c cccccccccccccccccccccccccccccccccccccccccccccccc
17d dddddddddddddddddddddddddddddddddddddddddddddddd
18e eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
19f ffffffffffffffffffffffffffffffffffffffffffffffff
20g gggggggggggggggggggggggggggggggggggggggggggggggg
21h hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
22i iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
23j jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
24k kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
25l llllllllllllllllllllllllllllllllllllllllllllllll
26m mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
27n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
28o oooooooooooooooooooooooooooooooooooooooooooooooo
29EOF
30
31cat >M <<\EOF &&
32A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
33B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
34C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
35D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
36E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
37F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
38G GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
39H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
40I IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
41J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
42K KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
43L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
44M MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
45N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
46O OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
47EOF
48
49git add A M &&
50git commit -m "initial has A and M" &&
51git branch white &&
52git branch red &&
53git branch blue &&
54git branch yellow &&
55git branch change &&
56git branch change+rename &&
57
58sed -e "/^g /s/.*/g : master changes a line/" <A >A+ &&
59mv A+ A &&
60git commit -a -m "master updates A" &&
61
62git checkout yellow &&
63rm -f M &&
64git commit -a -m "yellow removes M" &&
65
66git checkout white &&
67sed -e "/^g /s/.*/g : white changes a line/" <A >B &&
68sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
69rm -f A M &&
70git update-index --add --remove A B M N &&
71git commit -m "white renames A->B, M->N" &&
72
73git checkout red &&
74sed -e "/^g /s/.*/g : red changes a line/" <A >B &&
75sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
76rm -f A M &&
77git update-index --add --remove A B M N &&
78git commit -m "red renames A->B, M->N" &&
79
80git checkout blue &&
81sed -e "/^g /s/.*/g : blue changes a line/" <A >C &&
82sed -e "/^G /s/.*/G : colored branch changes a line/" <M >N &&
83rm -f A M &&
84git update-index --add --remove A C M N &&
85git commit -m "blue renames A->C, M->N" &&
86
87git checkout change &&
88sed -e "/^g /s/.*/g : changed line/" <A >A+ &&
89mv A+ A &&
90git commit -q -a -m "changed" &&
91
92git checkout change+rename &&
93sed -e "/^g /s/.*/g : changed line/" <A >B &&
94rm A &&
95git update-index --add B &&
96git commit -q -a -m "changed and renamed" &&
97
98git checkout master'
99
100test_expect_success 'pull renaming branch into unrenaming one' \
101'
102 git show-branch &&
103 test_expect_code 1 git pull . white &&
104 git ls-files -s &&
105 git ls-files -u B >b.stages &&
106 test_line_count = 3 b.stages &&
107 git ls-files -s N >n.stages &&
108 test_line_count = 1 n.stages &&
109 sed -ne "/^g/{
110 p
111 q
112 }" B | grep master &&
113 git diff --exit-code white N
114'
115
116test_expect_success 'pull renaming branch into another renaming one' \
117'
118 rm -f B &&
119 git reset --hard &&
120 git checkout red &&
121 test_expect_code 1 git pull . white &&
122 git ls-files -u B >b.stages &&
123 test_line_count = 3 b.stages &&
124 git ls-files -s N >n.stages &&
125 test_line_count = 1 n.stages &&
126 sed -ne "/^g/{
127 p
128 q
129 }" B | grep red &&
130 git diff --exit-code white N
131'
132
133test_expect_success 'pull unrenaming branch into renaming one' \
134'
135 git reset --hard &&
136 git show-branch &&
137 test_expect_code 1 git pull . master &&
138 git ls-files -u B >b.stages &&
139 test_line_count = 3 b.stages &&
140 git ls-files -s N >n.stages &&
141 test_line_count = 1 n.stages &&
142 sed -ne "/^g/{
143 p
144 q
145 }" B | grep red &&
146 git diff --exit-code white N
147'
148
149test_expect_success 'pull conflicting renames' \
150'
151 git reset --hard &&
152 git show-branch &&
153 test_expect_code 1 git pull . blue &&
154 git ls-files -u A >a.stages &&
155 test_line_count = 1 a.stages &&
156 git ls-files -u B >b.stages &&
157 test_line_count = 1 b.stages &&
158 git ls-files -u C >c.stages &&
159 test_line_count = 1 c.stages &&
160 git ls-files -s N >n.stages &&
161 test_line_count = 1 n.stages &&
162 sed -ne "/^g/{
163 p
164 q
165 }" B | grep red &&
166 git diff --exit-code white N
167'
168
169test_expect_success 'interference with untracked working tree file' '
170 git reset --hard &&
171 git show-branch &&
172 echo >A this file should not matter &&
173 test_expect_code 1 git pull . white &&
174 test_path_is_file A
175'
176
177test_expect_success 'interference with untracked working tree file' '
178 git reset --hard &&
179 git checkout white &&
180 git show-branch &&
181 rm -f A &&
182 echo >A this file should not matter &&
183 test_expect_code 1 git pull . red &&
184 test_path_is_file A
185'
186
187test_expect_success 'interference with untracked working tree file' '
188 git reset --hard &&
189 rm -f A M &&
190 git checkout -f master &&
191 git tag -f anchor &&
192 git show-branch &&
193 git pull . yellow &&
194 test_path_is_missing M &&
195 git reset --hard anchor
196'
197
198test_expect_success 'updated working tree file should prevent the merge' '
199 git reset --hard &&
200 rm -f A M &&
201 git checkout -f master &&
202 git tag -f anchor &&
203 git show-branch &&
204 echo >>M one line addition &&
205 cat M >M.saved &&
206 test_expect_code 128 git pull . yellow &&
207 test_cmp M M.saved &&
208 rm -f M.saved
209'
210
211test_expect_success 'updated working tree file should prevent the merge' '
212 git reset --hard &&
213 rm -f A M &&
214 git checkout -f master &&
215 git tag -f anchor &&
216 git show-branch &&
217 echo >>M one line addition &&
218 cat M >M.saved &&
219 git update-index M &&
220 test_expect_code 128 git pull . yellow &&
221 test_cmp M M.saved &&
222 rm -f M.saved
223'
224
225test_expect_success 'interference with untracked working tree file' '
226 git reset --hard &&
227 rm -f A M &&
228 git checkout -f yellow &&
229 git tag -f anchor &&
230 git show-branch &&
231 echo >M this file should not matter &&
232 git pull . master &&
233 test_path_is_file M &&
234 ! {
235 git ls-files -s |
236 grep M
237 } &&
238 git reset --hard anchor
239'
240
241test_expect_success 'merge of identical changes in a renamed file' '
242 rm -f A M N &&
243 git reset --hard &&
244 git checkout change+rename &&
245 GIT_MERGE_VERBOSITY=3 git merge change | grep "^Skipped B" &&
246 git reset --hard HEAD^ &&
247 git checkout change &&
248 GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B"
249'
250
251test_expect_success 'setup for rename + d/f conflicts' '
252 git reset --hard &&
253 git checkout --orphan dir-in-way &&
254 git rm -rf . &&
255 git clean -fdqx &&
256
257 mkdir sub &&
258 mkdir dir &&
259 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >sub/file &&
260 echo foo >dir/file-in-the-way &&
261 git add -A &&
262 git commit -m "Common commmit" &&
263
264 echo 11 >>sub/file &&
265 echo more >>dir/file-in-the-way &&
266 git add -u &&
267 git commit -m "Commit to merge, with dir in the way" &&
268
269 git checkout -b dir-not-in-way &&
270 git reset --soft HEAD^ &&
271 git rm -rf dir &&
272 git commit -m "Commit to merge, with dir removed" -- dir sub/file &&
273
274 git checkout -b renamed-file-has-no-conflicts dir-in-way~1 &&
275 git rm -rf dir &&
276 git rm sub/file &&
277 printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n" >dir &&
278 git add dir &&
279 git commit -m "Independent change" &&
280
281 git checkout -b renamed-file-has-conflicts dir-in-way~1 &&
282 git rm -rf dir &&
283 git mv sub/file dir &&
284 echo 12 >>dir &&
285 git add dir &&
286 git commit -m "Conflicting change"
287'
288
289printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n11\n" >expected
290
291test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' '
292 git reset --hard &&
293 git checkout -q renamed-file-has-no-conflicts^0 &&
294 git merge --strategy=recursive dir-not-in-way &&
295 git diff --quiet &&
296 test -f dir &&
297 test_cmp expected dir
298'
299
300test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' '
301 git reset --hard &&
302 rm -rf dir~* &&
303 git checkout -q renamed-file-has-no-conflicts^0 &&
304 test_must_fail git merge --strategy=recursive dir-in-way >output &&
305
306 grep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
307 grep "Auto-merging dir" output &&
308 grep "Adding as dir~HEAD instead" output &&
309
310 test 3 -eq "$(git ls-files -u | wc -l)" &&
311 test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
312
313 test_must_fail git diff --quiet &&
314 test_must_fail git diff --cached --quiet &&
315
316 test -f dir/file-in-the-way &&
317 test -f dir~HEAD &&
318 test_cmp expected dir~HEAD
319'
320
321test_expect_success 'Same as previous, but merged other way' '
322 git reset --hard &&
323 rm -rf dir~* &&
324 git checkout -q dir-in-way^0 &&
325 test_must_fail git merge --strategy=recursive renamed-file-has-no-conflicts >output 2>errors &&
326
327 ! grep "error: refusing to lose untracked file at" errors &&
328 grep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
329 grep "Auto-merging dir" output &&
330 grep "Adding as dir~renamed-file-has-no-conflicts instead" output &&
331
332 test 3 -eq "$(git ls-files -u | wc -l)" &&
333 test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
334
335 test_must_fail git diff --quiet &&
336 test_must_fail git diff --cached --quiet &&
337
338 test -f dir/file-in-the-way &&
339 test -f dir~renamed-file-has-no-conflicts &&
340 test_cmp expected dir~renamed-file-has-no-conflicts
341'
342
343cat >expected <<\EOF &&
3441
3452
3463
3474
3485
3496
3507
3518
3529
35310
354<<<<<<< HEAD:dir
35512
356=======
35711
358>>>>>>> dir-not-in-way:sub/file
359EOF
360
361test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in way' '
362 git reset --hard &&
363 rm -rf dir~* &&
364 git checkout -q renamed-file-has-conflicts^0 &&
365 test_must_fail git merge --strategy=recursive dir-not-in-way &&
366
367 test 3 -eq "$(git ls-files -u | wc -l)" &&
368 test 3 -eq "$(git ls-files -u dir | wc -l)" &&
369
370 test_must_fail git diff --quiet &&
371 test_must_fail git diff --cached --quiet &&
372
373 test -f dir &&
374 test_cmp expected dir
375'
376
377test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in the way' '
378 modify s/dir-not-in-way/dir-in-way/ expected &&
379
380 git reset --hard &&
381 rm -rf dir~* &&
382 git checkout -q renamed-file-has-conflicts^0 &&
383 test_must_fail git merge --strategy=recursive dir-in-way &&
384
385 test 5 -eq "$(git ls-files -u | wc -l)" &&
386 test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" &&
387 test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
388
389 test_must_fail git diff --quiet &&
390 test_must_fail git diff --cached --quiet &&
391
392 test -f dir/file-in-the-way &&
393 test -f dir~HEAD &&
394 test_cmp expected dir~HEAD
395'
396
397cat >expected <<\EOF &&
3981
3992
4003
4014
4025
4036
4047
4058
4069
40710
408<<<<<<< HEAD:sub/file
40911
410=======
41112
412>>>>>>> renamed-file-has-conflicts:dir
413EOF
414
415test_expect_success 'Same as previous, but merged other way' '
416 git reset --hard &&
417 rm -rf dir~* &&
418 git checkout -q dir-in-way^0 &&
419 test_must_fail git merge --strategy=recursive renamed-file-has-conflicts &&
420
421 test 5 -eq "$(git ls-files -u | wc -l)" &&
422 test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" &&
423 test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
424
425 test_must_fail git diff --quiet &&
426 test_must_fail git diff --cached --quiet &&
427
428 test -f dir/file-in-the-way &&
429 test -f dir~renamed-file-has-conflicts &&
430 test_cmp expected dir~renamed-file-has-conflicts
431'
432
433test_expect_success 'setup both rename source and destination involved in D/F conflict' '
434 git reset --hard &&
435 git checkout --orphan rename-dest &&
436 git rm -rf . &&
437 git clean -fdqx &&
438
439 mkdir one &&
440 echo stuff >one/file &&
441 git add -A &&
442 git commit -m "Common commmit" &&
443
444 git mv one/file destdir &&
445 git commit -m "Renamed to destdir" &&
446
447 git checkout -b source-conflict HEAD~1 &&
448 git rm -rf one &&
449 mkdir destdir &&
450 touch one destdir/foo &&
451 git add -A &&
452 git commit -m "Conflicts in the way"
453'
454
455test_expect_success 'both rename source and destination involved in D/F conflict' '
456 git reset --hard &&
457 rm -rf dir~* &&
458 git checkout -q rename-dest^0 &&
459 test_must_fail git merge --strategy=recursive source-conflict &&
460
461 test 1 -eq "$(git ls-files -u | wc -l)" &&
462
463 test_must_fail git diff --quiet &&
464
465 test -f destdir/foo &&
466 test -f one &&
467 test -f destdir~HEAD &&
468 test "stuff" = "$(cat destdir~HEAD)"
469'
470
471test_expect_success 'setup pair rename to parent of other (D/F conflicts)' '
472 git reset --hard &&
473 git checkout --orphan rename-two &&
474 git rm -rf . &&
475 git clean -fdqx &&
476
477 mkdir one &&
478 mkdir two &&
479 echo stuff >one/file &&
480 echo other >two/file &&
481 git add -A &&
482 git commit -m "Common commmit" &&
483
484 git rm -rf one &&
485 git mv two/file one &&
486 git commit -m "Rename two/file -> one" &&
487
488 git checkout -b rename-one HEAD~1 &&
489 git rm -rf two &&
490 git mv one/file two &&
491 rm -r one &&
492 git commit -m "Rename one/file -> two"
493'
494
495test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '
496 git checkout -q rename-one^0 &&
497 mkdir one &&
498 test_must_fail git merge --strategy=recursive rename-two &&
499
500 test 2 -eq "$(git ls-files -u | wc -l)" &&
501 test 1 -eq "$(git ls-files -u one | wc -l)" &&
502 test 1 -eq "$(git ls-files -u two | wc -l)" &&
503
504 test_must_fail git diff --quiet &&
505
506 test 4 -eq $(find . | grep -v .git | wc -l) &&
507
508 test -d one &&
509 test -f one~rename-two &&
510 test -f two &&
511 test "other" = $(cat one~rename-two) &&
512 test "stuff" = $(cat two)
513'
514
515test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean start' '
516 git reset --hard &&
517 git clean -fdqx &&
518 test_must_fail git merge --strategy=recursive rename-two &&
519
520 test 2 -eq "$(git ls-files -u | wc -l)" &&
521 test 1 -eq "$(git ls-files -u one | wc -l)" &&
522 test 1 -eq "$(git ls-files -u two | wc -l)" &&
523
524 test_must_fail git diff --quiet &&
525
526 test 3 -eq $(find . | grep -v .git | wc -l) &&
527
528 test -f one &&
529 test -f two &&
530 test "other" = $(cat one) &&
531 test "stuff" = $(cat two)
532'
533
534test_expect_success 'setup rename of one file to two, with directories in the way' '
535 git reset --hard &&
536 git checkout --orphan first-rename &&
537 git rm -rf . &&
538 git clean -fdqx &&
539
540 echo stuff >original &&
541 git add -A &&
542 git commit -m "Common commmit" &&
543
544 mkdir two &&
545 >two/file &&
546 git add two/file &&
547 git mv original one &&
548 git commit -m "Put two/file in the way, rename to one" &&
549
550 git checkout -b second-rename HEAD~1 &&
551 mkdir one &&
552 >one/file &&
553 git add one/file &&
554 git mv original two &&
555 git commit -m "Put one/file in the way, rename to two"
556'
557
558test_expect_success 'check handling of differently renamed file with D/F conflicts' '
559 git checkout -q first-rename^0 &&
560 test_must_fail git merge --strategy=recursive second-rename &&
561
562 test 5 -eq "$(git ls-files -s | wc -l)" &&
563 test 3 -eq "$(git ls-files -u | wc -l)" &&
564 test 1 -eq "$(git ls-files -u one | wc -l)" &&
565 test 1 -eq "$(git ls-files -u two | wc -l)" &&
566 test 1 -eq "$(git ls-files -u original | wc -l)" &&
567 test 2 -eq "$(git ls-files -o | wc -l)" &&
568
569 test -f one/file &&
570 test -f two/file &&
571 test -f one~HEAD &&
572 test -f two~second-rename &&
573 ! test -f original
574'
575
576test_expect_success 'setup rename one file to two; directories moving out of the way' '
577 git reset --hard &&
578 git checkout --orphan first-rename-redo &&
579 git rm -rf . &&
580 git clean -fdqx &&
581
582 echo stuff >original &&
583 mkdir one two &&
584 touch one/file two/file &&
585 git add -A &&
586 git commit -m "Common commmit" &&
587
588 git rm -rf one &&
589 git mv original one &&
590 git commit -m "Rename to one" &&
591
592 git checkout -b second-rename-redo HEAD~1 &&
593 git rm -rf two &&
594 git mv original two &&
595 git commit -m "Rename to two"
596'
597
598test_expect_success 'check handling of differently renamed file with D/F conflicts' '
599 git checkout -q first-rename-redo^0 &&
600 test_must_fail git merge --strategy=recursive second-rename-redo &&
601
602 test 3 -eq "$(git ls-files -u | wc -l)" &&
603 test 1 -eq "$(git ls-files -u one | wc -l)" &&
604 test 1 -eq "$(git ls-files -u two | wc -l)" &&
605 test 1 -eq "$(git ls-files -u original | wc -l)" &&
606 test 0 -eq "$(git ls-files -o | wc -l)" &&
607
608 test -f one &&
609 test -f two &&
610 ! test -f original
611'
612
613test_expect_success 'setup avoid unnecessary update, normal rename' '
614 git reset --hard &&
615 git checkout --orphan avoid-unnecessary-update-1 &&
616 git rm -rf . &&
617 git clean -fdqx &&
618
619 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >original &&
620 git add -A &&
621 git commit -m "Common commmit" &&
622
623 git mv original rename &&
624 echo 11 >>rename &&
625 git add -u &&
626 git commit -m "Renamed and modified" &&
627
628 git checkout -b merge-branch-1 HEAD~1 &&
629 echo "random content" >random-file &&
630 git add -A &&
631 git commit -m "Random, unrelated changes"
632'
633
634test_expect_success 'avoid unnecessary update, normal rename' '
635 git checkout -q avoid-unnecessary-update-1^0 &&
636 test-chmtime =1000000000 rename &&
637 test-chmtime -v +0 rename >expect &&
638 git merge merge-branch-1 &&
639 test-chmtime -v +0 rename >actual &&
640 test_cmp expect actual # "rename" should have stayed intact
641'
642
643test_expect_success 'setup to test avoiding unnecessary update, with D/F conflict' '
644 git reset --hard &&
645 git checkout --orphan avoid-unnecessary-update-2 &&
646 git rm -rf . &&
647 git clean -fdqx &&
648
649 mkdir df &&
650 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >df/file &&
651 git add -A &&
652 git commit -m "Common commmit" &&
653
654 git mv df/file temp &&
655 rm -rf df &&
656 git mv temp df &&
657 echo 11 >>df &&
658 git add -u &&
659 git commit -m "Renamed and modified" &&
660
661 git checkout -b merge-branch-2 HEAD~1 &&
662 >unrelated-change &&
663 git add unrelated-change &&
664 git commit -m "Only unrelated changes"
665'
666
667test_expect_success 'avoid unnecessary update, with D/F conflict' '
668 git checkout -q avoid-unnecessary-update-2^0 &&
669 test-chmtime =1000000000 df &&
670 test-chmtime -v +0 df >expect &&
671 git merge merge-branch-2 &&
672 test-chmtime -v +0 df >actual &&
673 test_cmp expect actual # "df" should have stayed intact
674'
675
676test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '
677 git rm -rf . &&
678 git clean -fdqx &&
679 rm -rf .git &&
680 git init &&
681
682 >irrelevant &&
683 mkdir df &&
684 >df/file &&
685 git add -A &&
686 git commit -mA &&
687
688 git checkout -b side
689 git rm -rf df &&
690 git commit -mB &&
691
692 git checkout master &&
693 git rm -rf df &&
694 echo bla >df &&
695 git add -A &&
696 git commit -m "Add a newfile"
697'
698
699test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '
700 git checkout -q master^0 &&
701 test-chmtime =1000000000 df &&
702 test-chmtime -v +0 df >expect &&
703 git merge side &&
704 test-chmtime -v +0 df >actual &&
705 test_cmp expect actual # "df" should have stayed intact
706'
707
708test_expect_success 'setup avoid unnecessary update, modify/delete' '
709 git rm -rf . &&
710 git clean -fdqx &&
711 rm -rf .git &&
712 git init &&
713
714 >irrelevant &&
715 >file &&
716 git add -A &&
717 git commit -mA &&
718
719 git checkout -b side
720 git rm -f file &&
721 git commit -m "Delete file" &&
722
723 git checkout master &&
724 echo bla >file &&
725 git add -A &&
726 git commit -m "Modify file"
727'
728
729test_expect_success 'avoid unnecessary update, modify/delete' '
730 git checkout -q master^0 &&
731 test-chmtime =1000000000 file &&
732 test-chmtime -v +0 file >expect &&
733 test_must_fail git merge side &&
734 test-chmtime -v +0 file >actual &&
735 test_cmp expect actual # "file" should have stayed intact
736'
737
738test_expect_success 'setup avoid unnecessary update, rename/add-dest' '
739 git rm -rf . &&
740 git clean -fdqx &&
741 rm -rf .git &&
742 git init &&
743
744 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >file &&
745 git add -A &&
746 git commit -mA &&
747
748 git checkout -b side
749 cp file newfile &&
750 git add -A &&
751 git commit -m "Add file copy" &&
752
753 git checkout master &&
754 git mv file newfile &&
755 git commit -m "Rename file"
756'
757
758test_expect_success 'avoid unnecessary update, rename/add-dest' '
759 git checkout -q master^0 &&
760 test-chmtime =1000000000 newfile &&
761 test-chmtime -v +0 newfile >expect &&
762 git merge side &&
763 test-chmtime -v +0 newfile >actual &&
764 test_cmp expect actual # "file" should have stayed intact
765'
766
767test_expect_success 'setup merge of rename + small change' '
768 git reset --hard &&
769 git checkout --orphan rename-plus-small-change &&
770 git rm -rf . &&
771 git clean -fdqx &&
772
773 echo ORIGINAL >file &&
774 git add file &&
775
776 test_tick &&
777 git commit -m Initial &&
778 git checkout -b rename_branch &&
779 git mv file renamed_file &&
780 git commit -m Rename &&
781 git checkout rename-plus-small-change &&
782 echo NEW-VERSION >file &&
783 git commit -a -m Reformat
784'
785
786test_expect_success 'merge rename + small change' '
787 git merge rename_branch &&
788
789 test 1 -eq $(git ls-files -s | wc -l) &&
790 test 0 -eq $(git ls-files -o | wc -l) &&
791 test $(git rev-parse HEAD:renamed_file) = $(git rev-parse HEAD~1:file)
792'
793
794test_expect_success 'setup for use of extended merge markers' '
795 git rm -rf . &&
796 git clean -fdqx &&
797 rm -rf .git &&
798 git init &&
799
800 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file &&
801 git add original_file &&
802 git commit -mA &&
803
804 git checkout -b rename &&
805 echo 9 >>original_file &&
806 git add original_file &&
807 git mv original_file renamed_file &&
808 git commit -mB &&
809
810 git checkout master &&
811 echo 8.5 >>original_file &&
812 git add original_file &&
813 git commit -mC
814'
815
816cat >expected <<\EOF &&
8171
8182
8193
8204
8215
8226
8237
8248
825<<<<<<< HEAD:renamed_file
8269
827=======
8288.5
829>>>>>>> master^0:original_file
830EOF
831
832test_expect_success 'merge master into rename has correct extended markers' '
833 git checkout rename^0 &&
834 test_must_fail git merge -s recursive master^0 &&
835 test_cmp expected renamed_file
836'
837
838cat >expected <<\EOF &&
8391
8402
8413
8424
8435
8446
8457
8468
847<<<<<<< HEAD:original_file
8488.5
849=======
8509
851>>>>>>> rename^0:renamed_file
852EOF
853
854test_expect_success 'merge rename into master has correct extended markers' '
855 git reset --hard &&
856 git checkout master^0 &&
857 test_must_fail git merge -s recursive rename^0 &&
858 test_cmp expected renamed_file
859'
860
861test_expect_success 'setup spurious "refusing to lose untracked" message' '
862 git rm -rf . &&
863 git clean -fdqx &&
864 rm -rf .git &&
865 git init &&
866
867 > irrelevant_file &&
868 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file &&
869 git add irrelevant_file original_file &&
870 git commit -mA &&
871
872 git checkout -b rename &&
873 git mv original_file renamed_file &&
874 git commit -mB &&
875
876 git checkout master &&
877 git rm original_file &&
878 git commit -mC
879'
880
881test_expect_success 'no spurious "refusing to lose untracked" message' '
882 git checkout master^0 &&
883 test_must_fail git merge rename^0 2>errors.txt &&
884 ! grep "refusing to lose untracked file" errors.txt
885'
886
887test_expect_success 'do not follow renames for empty files' '
888 git checkout -f -b empty-base &&
889 >empty1 &&
890 git add empty1 &&
891 git commit -m base &&
892 echo content >empty1 &&
893 git add empty1 &&
894 git commit -m fill &&
895 git checkout -b empty-topic HEAD^ &&
896 git mv empty1 empty2 &&
897 git commit -m rename &&
898 test_must_fail git merge empty-base &&
899 >expect &&
900 test_cmp expect empty2
901'
902
903test_done