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 >out &&
246 test_i18ngrep "^Skipped B" out &&
247 git reset --hard HEAD^ &&
248 git checkout change &&
249 GIT_MERGE_VERBOSITY=3 git merge change+rename >out &&
250 test_i18ngrep "^Skipped B" out
251'
252
253test_expect_success 'setup for rename + d/f conflicts' '
254 git reset --hard &&
255 git checkout --orphan dir-in-way &&
256 git rm -rf . &&
257 git clean -fdqx &&
258
259 mkdir sub &&
260 mkdir dir &&
261 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >sub/file &&
262 echo foo >dir/file-in-the-way &&
263 git add -A &&
264 git commit -m "Common commit" &&
265
266 echo 11 >>sub/file &&
267 echo more >>dir/file-in-the-way &&
268 git add -u &&
269 git commit -m "Commit to merge, with dir in the way" &&
270
271 git checkout -b dir-not-in-way &&
272 git reset --soft HEAD^ &&
273 git rm -rf dir &&
274 git commit -m "Commit to merge, with dir removed" -- dir sub/file &&
275
276 git checkout -b renamed-file-has-no-conflicts dir-in-way~1 &&
277 git rm -rf dir &&
278 git rm sub/file &&
279 printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n" >dir &&
280 git add dir &&
281 git commit -m "Independent change" &&
282
283 git checkout -b renamed-file-has-conflicts dir-in-way~1 &&
284 git rm -rf dir &&
285 git mv sub/file dir &&
286 echo 12 >>dir &&
287 git add dir &&
288 git commit -m "Conflicting change"
289'
290
291printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n11\n" >expected
292
293test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' '
294 git reset --hard &&
295 git checkout -q renamed-file-has-no-conflicts^0 &&
296 git merge --strategy=recursive dir-not-in-way &&
297 git diff --quiet &&
298 test -f dir &&
299 test_cmp expected dir
300'
301
302test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' '
303 git reset --hard &&
304 rm -rf dir~* &&
305 git checkout -q renamed-file-has-no-conflicts^0 &&
306 test_must_fail git merge --strategy=recursive dir-in-way >output &&
307
308 test_i18ngrep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
309 test_i18ngrep "Auto-merging dir" output &&
310 test_i18ngrep "Adding as dir~HEAD instead" output &&
311
312 test 3 -eq "$(git ls-files -u | wc -l)" &&
313 test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
314
315 test_must_fail git diff --quiet &&
316 test_must_fail git diff --cached --quiet &&
317
318 test -f dir/file-in-the-way &&
319 test -f dir~HEAD &&
320 test_cmp expected dir~HEAD
321'
322
323test_expect_success 'Same as previous, but merged other way' '
324 git reset --hard &&
325 rm -rf dir~* &&
326 git checkout -q dir-in-way^0 &&
327 test_must_fail git merge --strategy=recursive renamed-file-has-no-conflicts >output 2>errors &&
328
329 ! grep "error: refusing to lose untracked file at" errors &&
330 test_i18ngrep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
331 test_i18ngrep "Auto-merging dir" output &&
332 test_i18ngrep "Adding as dir~renamed-file-has-no-conflicts instead" output &&
333
334 test 3 -eq "$(git ls-files -u | wc -l)" &&
335 test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
336
337 test_must_fail git diff --quiet &&
338 test_must_fail git diff --cached --quiet &&
339
340 test -f dir/file-in-the-way &&
341 test -f dir~renamed-file-has-no-conflicts &&
342 test_cmp expected dir~renamed-file-has-no-conflicts
343'
344
345cat >expected <<\EOF &&
3461
3472
3483
3494
3505
3516
3527
3538
3549
35510
356<<<<<<< HEAD:dir
35712
358=======
35911
360>>>>>>> dir-not-in-way:sub/file
361EOF
362
363test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in way' '
364 git reset --hard &&
365 rm -rf dir~* &&
366 git checkout -q renamed-file-has-conflicts^0 &&
367 test_must_fail git merge --strategy=recursive dir-not-in-way &&
368
369 test 3 -eq "$(git ls-files -u | wc -l)" &&
370 test 3 -eq "$(git ls-files -u dir | wc -l)" &&
371
372 test_must_fail git diff --quiet &&
373 test_must_fail git diff --cached --quiet &&
374
375 test -f dir &&
376 test_cmp expected dir
377'
378
379test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in the way' '
380 modify s/dir-not-in-way/dir-in-way/ expected &&
381
382 git reset --hard &&
383 rm -rf dir~* &&
384 git checkout -q renamed-file-has-conflicts^0 &&
385 test_must_fail git merge --strategy=recursive dir-in-way &&
386
387 test 5 -eq "$(git ls-files -u | wc -l)" &&
388 test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" &&
389 test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
390
391 test_must_fail git diff --quiet &&
392 test_must_fail git diff --cached --quiet &&
393
394 test -f dir/file-in-the-way &&
395 test -f dir~HEAD &&
396 test_cmp expected dir~HEAD
397'
398
399cat >expected <<\EOF &&
4001
4012
4023
4034
4045
4056
4067
4078
4089
40910
410<<<<<<< HEAD:sub/file
41111
412=======
41312
414>>>>>>> renamed-file-has-conflicts:dir
415EOF
416
417test_expect_success 'Same as previous, but merged other way' '
418 git reset --hard &&
419 rm -rf dir~* &&
420 git checkout -q dir-in-way^0 &&
421 test_must_fail git merge --strategy=recursive renamed-file-has-conflicts &&
422
423 test 5 -eq "$(git ls-files -u | wc -l)" &&
424 test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" &&
425 test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
426
427 test_must_fail git diff --quiet &&
428 test_must_fail git diff --cached --quiet &&
429
430 test -f dir/file-in-the-way &&
431 test -f dir~renamed-file-has-conflicts &&
432 test_cmp expected dir~renamed-file-has-conflicts
433'
434
435test_expect_success 'setup both rename source and destination involved in D/F conflict' '
436 git reset --hard &&
437 git checkout --orphan rename-dest &&
438 git rm -rf . &&
439 git clean -fdqx &&
440
441 mkdir one &&
442 echo stuff >one/file &&
443 git add -A &&
444 git commit -m "Common commit" &&
445
446 git mv one/file destdir &&
447 git commit -m "Renamed to destdir" &&
448
449 git checkout -b source-conflict HEAD~1 &&
450 git rm -rf one &&
451 mkdir destdir &&
452 touch one destdir/foo &&
453 git add -A &&
454 git commit -m "Conflicts in the way"
455'
456
457test_expect_success 'both rename source and destination involved in D/F conflict' '
458 git reset --hard &&
459 rm -rf dir~* &&
460 git checkout -q rename-dest^0 &&
461 test_must_fail git merge --strategy=recursive source-conflict &&
462
463 test 1 -eq "$(git ls-files -u | wc -l)" &&
464
465 test_must_fail git diff --quiet &&
466
467 test -f destdir/foo &&
468 test -f one &&
469 test -f destdir~HEAD &&
470 test "stuff" = "$(cat destdir~HEAD)"
471'
472
473test_expect_success 'setup pair rename to parent of other (D/F conflicts)' '
474 git reset --hard &&
475 git checkout --orphan rename-two &&
476 git rm -rf . &&
477 git clean -fdqx &&
478
479 mkdir one &&
480 mkdir two &&
481 echo stuff >one/file &&
482 echo other >two/file &&
483 git add -A &&
484 git commit -m "Common commit" &&
485
486 git rm -rf one &&
487 git mv two/file one &&
488 git commit -m "Rename two/file -> one" &&
489
490 git checkout -b rename-one HEAD~1 &&
491 git rm -rf two &&
492 git mv one/file two &&
493 rm -r one &&
494 git commit -m "Rename one/file -> two"
495'
496
497test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '
498 git checkout -q rename-one^0 &&
499 mkdir one &&
500 test_must_fail git merge --strategy=recursive rename-two &&
501
502 test 2 -eq "$(git ls-files -u | wc -l)" &&
503 test 1 -eq "$(git ls-files -u one | wc -l)" &&
504 test 1 -eq "$(git ls-files -u two | wc -l)" &&
505
506 test_must_fail git diff --quiet &&
507
508 test 4 -eq $(find . | grep -v .git | wc -l) &&
509
510 test -d one &&
511 test -f one~rename-two &&
512 test -f two &&
513 test "other" = $(cat one~rename-two) &&
514 test "stuff" = $(cat two)
515'
516
517test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean start' '
518 git reset --hard &&
519 git clean -fdqx &&
520 test_must_fail git merge --strategy=recursive rename-two &&
521
522 test 2 -eq "$(git ls-files -u | wc -l)" &&
523 test 1 -eq "$(git ls-files -u one | wc -l)" &&
524 test 1 -eq "$(git ls-files -u two | wc -l)" &&
525
526 test_must_fail git diff --quiet &&
527
528 test 3 -eq $(find . | grep -v .git | wc -l) &&
529
530 test -f one &&
531 test -f two &&
532 test "other" = $(cat one) &&
533 test "stuff" = $(cat two)
534'
535
536test_expect_success 'setup rename of one file to two, with directories in the way' '
537 git reset --hard &&
538 git checkout --orphan first-rename &&
539 git rm -rf . &&
540 git clean -fdqx &&
541
542 echo stuff >original &&
543 git add -A &&
544 git commit -m "Common commit" &&
545
546 mkdir two &&
547 >two/file &&
548 git add two/file &&
549 git mv original one &&
550 git commit -m "Put two/file in the way, rename to one" &&
551
552 git checkout -b second-rename HEAD~1 &&
553 mkdir one &&
554 >one/file &&
555 git add one/file &&
556 git mv original two &&
557 git commit -m "Put one/file in the way, rename to two"
558'
559
560test_expect_success 'check handling of differently renamed file with D/F conflicts' '
561 git checkout -q first-rename^0 &&
562 test_must_fail git merge --strategy=recursive second-rename &&
563
564 test 5 -eq "$(git ls-files -s | wc -l)" &&
565 test 3 -eq "$(git ls-files -u | wc -l)" &&
566 test 1 -eq "$(git ls-files -u one | wc -l)" &&
567 test 1 -eq "$(git ls-files -u two | wc -l)" &&
568 test 1 -eq "$(git ls-files -u original | wc -l)" &&
569 test 2 -eq "$(git ls-files -o | wc -l)" &&
570
571 test -f one/file &&
572 test -f two/file &&
573 test -f one~HEAD &&
574 test -f two~second-rename &&
575 ! test -f original
576'
577
578test_expect_success 'setup rename one file to two; directories moving out of the way' '
579 git reset --hard &&
580 git checkout --orphan first-rename-redo &&
581 git rm -rf . &&
582 git clean -fdqx &&
583
584 echo stuff >original &&
585 mkdir one two &&
586 touch one/file two/file &&
587 git add -A &&
588 git commit -m "Common commit" &&
589
590 git rm -rf one &&
591 git mv original one &&
592 git commit -m "Rename to one" &&
593
594 git checkout -b second-rename-redo HEAD~1 &&
595 git rm -rf two &&
596 git mv original two &&
597 git commit -m "Rename to two"
598'
599
600test_expect_success 'check handling of differently renamed file with D/F conflicts' '
601 git checkout -q first-rename-redo^0 &&
602 test_must_fail git merge --strategy=recursive second-rename-redo &&
603
604 test 3 -eq "$(git ls-files -u | wc -l)" &&
605 test 1 -eq "$(git ls-files -u one | wc -l)" &&
606 test 1 -eq "$(git ls-files -u two | wc -l)" &&
607 test 1 -eq "$(git ls-files -u original | wc -l)" &&
608 test 0 -eq "$(git ls-files -o | wc -l)" &&
609
610 test -f one &&
611 test -f two &&
612 ! test -f original
613'
614
615test_expect_success 'setup avoid unnecessary update, normal rename' '
616 git reset --hard &&
617 git checkout --orphan avoid-unnecessary-update-1 &&
618 git rm -rf . &&
619 git clean -fdqx &&
620
621 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >original &&
622 git add -A &&
623 git commit -m "Common commit" &&
624
625 git mv original rename &&
626 echo 11 >>rename &&
627 git add -u &&
628 git commit -m "Renamed and modified" &&
629
630 git checkout -b merge-branch-1 HEAD~1 &&
631 echo "random content" >random-file &&
632 git add -A &&
633 git commit -m "Random, unrelated changes"
634'
635
636test_expect_success 'avoid unnecessary update, normal rename' '
637 git checkout -q avoid-unnecessary-update-1^0 &&
638 test-tool chmtime =1000000000 rename &&
639 test-tool chmtime -v +0 rename >expect &&
640 git merge merge-branch-1 &&
641 test-tool chmtime -v +0 rename >actual &&
642 test_cmp expect actual # "rename" should have stayed intact
643'
644
645test_expect_success 'setup to test avoiding unnecessary update, with D/F conflict' '
646 git reset --hard &&
647 git checkout --orphan avoid-unnecessary-update-2 &&
648 git rm -rf . &&
649 git clean -fdqx &&
650
651 mkdir df &&
652 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >df/file &&
653 git add -A &&
654 git commit -m "Common commit" &&
655
656 git mv df/file temp &&
657 rm -rf df &&
658 git mv temp df &&
659 echo 11 >>df &&
660 git add -u &&
661 git commit -m "Renamed and modified" &&
662
663 git checkout -b merge-branch-2 HEAD~1 &&
664 >unrelated-change &&
665 git add unrelated-change &&
666 git commit -m "Only unrelated changes"
667'
668
669test_expect_success 'avoid unnecessary update, with D/F conflict' '
670 git checkout -q avoid-unnecessary-update-2^0 &&
671 test-tool chmtime =1000000000 df &&
672 test-tool chmtime -v +0 df >expect &&
673 git merge merge-branch-2 &&
674 test-tool chmtime -v +0 df >actual &&
675 test_cmp expect actual # "df" should have stayed intact
676'
677
678test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '
679 git rm -rf . &&
680 git clean -fdqx &&
681 rm -rf .git &&
682 git init &&
683
684 >irrelevant &&
685 mkdir df &&
686 >df/file &&
687 git add -A &&
688 git commit -mA &&
689
690 git checkout -b side &&
691 git rm -rf df &&
692 git commit -mB &&
693
694 git checkout master &&
695 git rm -rf df &&
696 echo bla >df &&
697 git add -A &&
698 git commit -m "Add a newfile"
699'
700
701test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '
702 git checkout -q master^0 &&
703 test-tool chmtime =1000000000 df &&
704 test-tool chmtime -v +0 df >expect &&
705 git merge side &&
706 test-tool chmtime -v +0 df >actual &&
707 test_cmp expect actual # "df" should have stayed intact
708'
709
710test_expect_success 'setup avoid unnecessary update, modify/delete' '
711 git rm -rf . &&
712 git clean -fdqx &&
713 rm -rf .git &&
714 git init &&
715
716 >irrelevant &&
717 >file &&
718 git add -A &&
719 git commit -mA &&
720
721 git checkout -b side &&
722 git rm -f file &&
723 git commit -m "Delete file" &&
724
725 git checkout master &&
726 echo bla >file &&
727 git add -A &&
728 git commit -m "Modify file"
729'
730
731test_expect_success 'avoid unnecessary update, modify/delete' '
732 git checkout -q master^0 &&
733 test-tool chmtime =1000000000 file &&
734 test-tool chmtime -v +0 file >expect &&
735 test_must_fail git merge side &&
736 test-tool chmtime -v +0 file >actual &&
737 test_cmp expect actual # "file" should have stayed intact
738'
739
740test_expect_success 'setup avoid unnecessary update, rename/add-dest' '
741 git rm -rf . &&
742 git clean -fdqx &&
743 rm -rf .git &&
744 git init &&
745
746 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >file &&
747 git add -A &&
748 git commit -mA &&
749
750 git checkout -b side &&
751 cp file newfile &&
752 git add -A &&
753 git commit -m "Add file copy" &&
754
755 git checkout master &&
756 git mv file newfile &&
757 git commit -m "Rename file"
758'
759
760test_expect_success 'avoid unnecessary update, rename/add-dest' '
761 git checkout -q master^0 &&
762 test-tool chmtime =1000000000 newfile &&
763 test-tool chmtime -v +0 newfile >expect &&
764 git merge side &&
765 test-tool chmtime -v +0 newfile >actual &&
766 test_cmp expect actual # "file" should have stayed intact
767'
768
769test_expect_success 'setup merge of rename + small change' '
770 git reset --hard &&
771 git checkout --orphan rename-plus-small-change &&
772 git rm -rf . &&
773 git clean -fdqx &&
774
775 echo ORIGINAL >file &&
776 git add file &&
777
778 test_tick &&
779 git commit -m Initial &&
780 git checkout -b rename_branch &&
781 git mv file renamed_file &&
782 git commit -m Rename &&
783 git checkout rename-plus-small-change &&
784 echo NEW-VERSION >file &&
785 git commit -a -m Reformat
786'
787
788test_expect_success 'merge rename + small change' '
789 git merge rename_branch &&
790
791 test 1 -eq $(git ls-files -s | wc -l) &&
792 test 0 -eq $(git ls-files -o | wc -l) &&
793 test $(git rev-parse HEAD:renamed_file) = $(git rev-parse HEAD~1:file)
794'
795
796test_expect_success 'setup for use of extended merge markers' '
797 git rm -rf . &&
798 git clean -fdqx &&
799 rm -rf .git &&
800 git init &&
801
802 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file &&
803 git add original_file &&
804 git commit -mA &&
805
806 git checkout -b rename &&
807 echo 9 >>original_file &&
808 git add original_file &&
809 git mv original_file renamed_file &&
810 git commit -mB &&
811
812 git checkout master &&
813 echo 8.5 >>original_file &&
814 git add original_file &&
815 git commit -mC
816'
817
818cat >expected <<\EOF &&
8191
8202
8213
8224
8235
8246
8257
8268
827<<<<<<< HEAD:renamed_file
8289
829=======
8308.5
831>>>>>>> master^0:original_file
832EOF
833
834test_expect_success 'merge master into rename has correct extended markers' '
835 git checkout rename^0 &&
836 test_must_fail git merge -s recursive master^0 &&
837 test_cmp expected renamed_file
838'
839
840cat >expected <<\EOF &&
8411
8422
8433
8444
8455
8466
8477
8488
849<<<<<<< HEAD:original_file
8508.5
851=======
8529
853>>>>>>> rename^0:renamed_file
854EOF
855
856test_expect_success 'merge rename into master has correct extended markers' '
857 git reset --hard &&
858 git checkout master^0 &&
859 test_must_fail git merge -s recursive rename^0 &&
860 test_cmp expected renamed_file
861'
862
863test_expect_success 'setup spurious "refusing to lose untracked" message' '
864 git rm -rf . &&
865 git clean -fdqx &&
866 rm -rf .git &&
867 git init &&
868
869 > irrelevant_file &&
870 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file &&
871 git add irrelevant_file original_file &&
872 git commit -mA &&
873
874 git checkout -b rename &&
875 git mv original_file renamed_file &&
876 git commit -mB &&
877
878 git checkout master &&
879 git rm original_file &&
880 git commit -mC
881'
882
883test_expect_success 'no spurious "refusing to lose untracked" message' '
884 git checkout master^0 &&
885 test_must_fail git merge rename^0 2>errors.txt &&
886 ! grep "refusing to lose untracked file" errors.txt
887'
888
889test_expect_success 'do not follow renames for empty files' '
890 git checkout -f -b empty-base &&
891 >empty1 &&
892 git add empty1 &&
893 git commit -m base &&
894 echo content >empty1 &&
895 git add empty1 &&
896 git commit -m fill &&
897 git checkout -b empty-topic HEAD^ &&
898 git mv empty1 empty2 &&
899 git commit -m rename &&
900 test_must_fail git merge empty-base &&
901 >expect &&
902 test_cmp expect empty2
903'
904
905test_done