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 --get =1000000000 rename >expect &&
639 git merge merge-branch-1 &&
640 test-tool chmtime --get rename >actual &&
641 test_cmp expect actual # "rename" should have stayed intact
642'
643
644test_expect_success 'setup to test avoiding unnecessary update, with D/F conflict' '
645 git reset --hard &&
646 git checkout --orphan avoid-unnecessary-update-2 &&
647 git rm -rf . &&
648 git clean -fdqx &&
649
650 mkdir df &&
651 printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >df/file &&
652 git add -A &&
653 git commit -m "Common commit" &&
654
655 git mv df/file temp &&
656 rm -rf df &&
657 git mv temp df &&
658 echo 11 >>df &&
659 git add -u &&
660 git commit -m "Renamed and modified" &&
661
662 git checkout -b merge-branch-2 HEAD~1 &&
663 >unrelated-change &&
664 git add unrelated-change &&
665 git commit -m "Only unrelated changes"
666'
667
668test_expect_success 'avoid unnecessary update, with D/F conflict' '
669 git checkout -q avoid-unnecessary-update-2^0 &&
670 test-tool chmtime --get =1000000000 df >expect &&
671 git merge merge-branch-2 &&
672 test-tool chmtime --get 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-tool chmtime --get =1000000000 df >expect &&
702 git merge side &&
703 test-tool chmtime --get df >actual &&
704 test_cmp expect actual # "df" should have stayed intact
705'
706
707test_expect_success 'setup avoid unnecessary update, modify/delete' '
708 git rm -rf . &&
709 git clean -fdqx &&
710 rm -rf .git &&
711 git init &&
712
713 >irrelevant &&
714 >file &&
715 git add -A &&
716 git commit -mA &&
717
718 git checkout -b side &&
719 git rm -f file &&
720 git commit -m "Delete file" &&
721
722 git checkout master &&
723 echo bla >file &&
724 git add -A &&
725 git commit -m "Modify file"
726'
727
728test_expect_success 'avoid unnecessary update, modify/delete' '
729 git checkout -q master^0 &&
730 test-tool chmtime --get =1000000000 file >expect &&
731 test_must_fail git merge side &&
732 test-tool chmtime --get file >actual &&
733 test_cmp expect actual # "file" should have stayed intact
734'
735
736test_expect_success 'setup avoid unnecessary update, rename/add-dest' '
737 git rm -rf . &&
738 git clean -fdqx &&
739 rm -rf .git &&
740 git init &&
741
742 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >file &&
743 git add -A &&
744 git commit -mA &&
745
746 git checkout -b side &&
747 cp file newfile &&
748 git add -A &&
749 git commit -m "Add file copy" &&
750
751 git checkout master &&
752 git mv file newfile &&
753 git commit -m "Rename file"
754'
755
756test_expect_success 'avoid unnecessary update, rename/add-dest' '
757 git checkout -q master^0 &&
758 test-tool chmtime --get =1000000000 newfile >expect &&
759 git merge side &&
760 test-tool chmtime --get newfile >actual &&
761 test_cmp expect actual # "file" should have stayed intact
762'
763
764test_expect_success 'setup merge of rename + small change' '
765 git reset --hard &&
766 git checkout --orphan rename-plus-small-change &&
767 git rm -rf . &&
768 git clean -fdqx &&
769
770 echo ORIGINAL >file &&
771 git add file &&
772
773 test_tick &&
774 git commit -m Initial &&
775 git checkout -b rename_branch &&
776 git mv file renamed_file &&
777 git commit -m Rename &&
778 git checkout rename-plus-small-change &&
779 echo NEW-VERSION >file &&
780 git commit -a -m Reformat
781'
782
783test_expect_success 'merge rename + small change' '
784 git merge rename_branch &&
785
786 test 1 -eq $(git ls-files -s | wc -l) &&
787 test 0 -eq $(git ls-files -o | wc -l) &&
788 test $(git rev-parse HEAD:renamed_file) = $(git rev-parse HEAD~1:file)
789'
790
791test_expect_success 'setup for use of extended merge markers' '
792 git rm -rf . &&
793 git clean -fdqx &&
794 rm -rf .git &&
795 git init &&
796
797 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file &&
798 git add original_file &&
799 git commit -mA &&
800
801 git checkout -b rename &&
802 echo 9 >>original_file &&
803 git add original_file &&
804 git mv original_file renamed_file &&
805 git commit -mB &&
806
807 git checkout master &&
808 echo 8.5 >>original_file &&
809 git add original_file &&
810 git commit -mC
811'
812
813cat >expected <<\EOF &&
8141
8152
8163
8174
8185
8196
8207
8218
822<<<<<<< HEAD:renamed_file
8239
824=======
8258.5
826>>>>>>> master^0:original_file
827EOF
828
829test_expect_success 'merge master into rename has correct extended markers' '
830 git checkout rename^0 &&
831 test_must_fail git merge -s recursive master^0 &&
832 test_cmp expected renamed_file
833'
834
835cat >expected <<\EOF &&
8361
8372
8383
8394
8405
8416
8427
8438
844<<<<<<< HEAD:original_file
8458.5
846=======
8479
848>>>>>>> rename^0:renamed_file
849EOF
850
851test_expect_success 'merge rename into master has correct extended markers' '
852 git reset --hard &&
853 git checkout master^0 &&
854 test_must_fail git merge -s recursive rename^0 &&
855 test_cmp expected renamed_file
856'
857
858test_expect_success 'setup spurious "refusing to lose untracked" message' '
859 git rm -rf . &&
860 git clean -fdqx &&
861 rm -rf .git &&
862 git init &&
863
864 > irrelevant_file &&
865 printf "1\n2\n3\n4\n5\n6\n7\n8\n" >original_file &&
866 git add irrelevant_file original_file &&
867 git commit -mA &&
868
869 git checkout -b rename &&
870 git mv original_file renamed_file &&
871 git commit -mB &&
872
873 git checkout master &&
874 git rm original_file &&
875 git commit -mC
876'
877
878test_expect_success 'no spurious "refusing to lose untracked" message' '
879 git checkout master^0 &&
880 test_must_fail git merge rename^0 2>errors.txt &&
881 ! grep "refusing to lose untracked file" errors.txt
882'
883
884test_expect_success 'do not follow renames for empty files' '
885 git checkout -f -b empty-base &&
886 >empty1 &&
887 git add empty1 &&
888 git commit -m base &&
889 echo content >empty1 &&
890 git add empty1 &&
891 git commit -m fill &&
892 git checkout -b empty-topic HEAD^ &&
893 git mv empty1 empty2 &&
894 git commit -m rename &&
895 test_must_fail git merge empty-base &&
896 >expect &&
897 test_cmp expect empty2
898'
899
900test_done