3 test_description
="recursive merge corner cases w/ renames but not criss-crosses"
4 # t6036 has corner cases that involve both criss-cross merges and renames
6 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
7 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
9 TEST_PASSES_SANITIZE_LEAK
=true
11 .
"$TEST_DIRECTORY"/lib-merge.sh
13 test_setup_rename_delete_untracked
() {
14 git init rename-delete-untracked
&&
16 cd rename-delete-untracked
&&
18 echo "A pretty inscription" >ring
&&
21 git commit
-m beginning
&&
24 git checkout
-b rename-the-ring
&&
25 git
mv ring one-ring-to-rule-them-all
&&
27 git commit
-m fullname
&&
29 git checkout people
&&
34 git commit
-m track-people-instead-of-objects
&&
35 echo "Myyy PRECIOUSSS" >ring
39 test_expect_success
"Does git preserve Gollum's precious artifact?" '
40 test_setup_rename_delete_untracked &&
42 cd rename-delete-untracked &&
44 test_must_fail git merge -s recursive rename-the-ring &&
46 # Make sure git did not delete an untracked file
47 test_path_is_file ring
51 # Testcase setup for rename/modify/add-source:
52 # Commit A: new file: a
53 # Commit B: modify a slightly
54 # Commit C: rename a->b, add completely different a
56 # We should be able to merge B & C cleanly
58 test_setup_rename_modify_add_source
() {
59 git init rename-modify-add-source
&&
61 cd rename-modify-add-source
&&
63 printf "1\n2\n3\n4\n5\n6\n7\n" >a
&&
68 git checkout
-b B A
&&
73 git checkout
-b C A
&&
75 echo something completely different
>a
&&
81 test_expect_failure
'rename/modify/add-source conflict resolvable' '
82 test_setup_rename_modify_add_source &&
84 cd rename-modify-add-source &&
88 git merge -s recursive C^0 &&
90 git rev-parse >expect \
92 git rev-parse >actual \
94 test_cmp expect actual
98 test_setup_break_detection_1
() {
99 git init break-detection-1
&&
101 cd break-detection-1
&&
103 printf "1\n2\n3\n4\n5\n" >a
&&
109 git checkout
-b B A
&&
111 echo "Completely different content" >a
&&
115 git checkout
-b C A
&&
122 test_expect_failure
'conflict caused if rename not detected' '
123 test_setup_break_detection_1 &&
125 cd break-detection-1 &&
127 git checkout -q C^0 &&
128 git merge -s recursive B^0 &&
130 git ls-files -s >out &&
131 test_line_count = 3 out &&
132 git ls-files -u >out &&
133 test_line_count = 0 out &&
134 git ls-files -o >out &&
135 test_line_count = 1 out &&
137 test_line_count = 6 c &&
138 git rev-parse >expect \
140 git rev-parse >actual \
142 test_cmp expect actual
146 test_setup_break_detection_2
() {
147 git init break-detection-2
&&
149 cd break-detection-2
&&
151 printf "1\n2\n3\n4\n5\n" >a
&&
157 git checkout
-b D A
&&
161 echo "Completely different content" >a
&&
165 git checkout
-b E A
&&
167 echo "Completely different content" >>a
&&
173 test_expect_failure
'missed conflict if rename not detected' '
174 test_setup_break_detection_2 &&
176 cd break-detection-2 &&
178 git checkout -q E^0 &&
179 test_must_fail git merge -s recursive D^0
183 # Tests for undetected rename/add-source causing a file to erroneously be
184 # deleted (and for mishandled rename/rename(1to1) causing the same issue).
186 # This test uses a rename/rename(1to1)+add-source conflict (1to1 means the
187 # same file is renamed on both sides to the same thing; it should trigger
188 # the 1to2 logic, which it would do if the add-source didn't cause issues
189 # for git's rename detection):
190 # Commit A: new file: a
191 # Commit B: rename a->b
192 # Commit C: rename a->b, add unrelated a
194 test_setup_break_detection_3
() {
195 git init break-detection-3
&&
197 cd break-detection-3
&&
199 printf "1\n2\n3\n4\n5\n" >a
&&
204 git checkout
-b B A
&&
208 git checkout
-b C A
&&
216 test_expect_failure
'detect rename/add-source and preserve all data' '
217 test_setup_break_detection_3 &&
219 cd break-detection-3 &&
223 git merge -s recursive C^0 &&
225 git ls-files -s >out &&
226 test_line_count = 2 out &&
227 git ls-files -u >out &&
228 test_line_count = 2 out &&
229 git ls-files -o >out &&
230 test_line_count = 1 out &&
232 test_path_is_file a &&
233 test_path_is_file b &&
235 git rev-parse >expect \
237 git rev-parse >actual \
239 test_cmp expect actual
243 test_expect_failure
'detect rename/add-source and preserve all data, merge other way' '
244 test_setup_break_detection_3 &&
246 cd break-detection-3 &&
250 git merge -s recursive B^0 &&
252 git ls-files -s >out &&
253 test_line_count = 2 out &&
254 git ls-files -u >out &&
255 test_line_count = 2 out &&
256 git ls-files -o >out &&
257 test_line_count = 1 out &&
259 test_path_is_file a &&
260 test_path_is_file b &&
262 git rev-parse >expect \
264 git rev-parse >actual \
266 test_cmp expect actual
270 test_setup_rename_directory
() {
271 git init rename-directory-
$1 &&
273 cd rename-directory-
$1 &&
275 printf "1\n2\n3\n4\n5\n6\n" >file &&
278 git commit
-m base
&&
281 git checkout
-b right
&&
284 echo junk
>newfile
/realfile
&&
285 git add
file newfile
/realfile
&&
287 git commit
-m right
&&
289 git checkout
-b left-conflict base
&&
292 git
mv file newfile
&&
294 git commit
-m left
&&
296 git checkout
-b left-clean base
&&
298 cat file >>newfile
&&
306 test_expect_success
'rename/directory conflict + clean content merge' '
307 test_setup_rename_directory 1a &&
309 cd rename-directory-1a &&
311 git checkout left-clean^0 &&
313 test_must_fail git merge -s recursive right^0 &&
315 git ls-files -s >out &&
316 test_line_count = 2 out &&
317 git ls-files -u >out &&
318 test_line_count = 1 out &&
319 git ls-files -o >out &&
320 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
322 test_line_count = 1 out
324 test_line_count = 2 out
328 git cat-file -p base:file >>expect &&
330 test_cmp expect newfile~HEAD &&
332 test_path_is_file newfile/realfile &&
333 test_path_is_file newfile~HEAD
337 test_expect_success
'rename/directory conflict + content merge conflict' '
338 test_setup_rename_directory 1b &&
340 cd rename-directory-1b &&
345 git checkout left-conflict^0 &&
347 test_must_fail git merge -s recursive right^0 &&
349 git ls-files -s >out &&
350 test_line_count = 4 out &&
351 git ls-files -u >out &&
352 test_line_count = 3 out &&
353 git ls-files -o >out &&
354 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
356 test_line_count = 1 out
358 test_line_count = 2 out
361 git cat-file -p left-conflict:newfile >left &&
362 git cat-file -p base:file >base &&
363 git cat-file -p right:file >right &&
364 test_must_fail git merge-file \
369 test_cmp left newfile~HEAD &&
371 git rev-parse >expect \
372 base:file left-conflict:newfile right:file &&
373 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
375 git rev-parse >actual \
376 :1:newfile~HEAD :2:newfile~HEAD :3:newfile~HEAD
378 git rev-parse >actual \
379 :1:newfile :2:newfile :3:newfile
381 test_cmp expect actual &&
383 test_path_is_file newfile/realfile &&
384 test_path_is_file newfile~HEAD
388 test_setup_rename_directory_2
() {
389 git init rename-directory-2
&&
391 cd rename-directory-2
&&
394 printf "1\n2\n3\n4\n5\n6\n" >sub
/file &&
397 git commit
-m base
&&
400 git checkout
-b right
&&
404 git commit
-m right
&&
406 git checkout
-b left base
&&
408 cat sub
/file >>newfile
&&
417 test_expect_success
'disappearing dir in rename/directory conflict handled' '
418 test_setup_rename_directory_2 &&
420 cd rename-directory-2 &&
422 git checkout left^0 &&
424 git merge -s recursive right^0 &&
426 git ls-files -s >out &&
427 test_line_count = 1 out &&
428 git ls-files -u >out &&
429 test_line_count = 0 out &&
430 git ls-files -o >out &&
431 test_line_count = 1 out &&
434 git cat-file -p base:sub/file >>expect &&
436 test_cmp expect sub &&
438 test_path_is_file sub
442 # Test for basic rename/add-dest conflict, with rename needing content merge:
444 # Commit A: rename a->b, modifying b too
445 # Commit B: modify a, add different b
447 test_setup_rename_with_content_merge_and_add
() {
448 git init rename-with-content-merge-and-add-
$1 &&
450 cd rename-with-content-merge-and-add-
$1 &&
457 git checkout
-b A O
&&
463 git checkout
-b B O
&&
465 echo hello world
>b
&&
471 test_expect_success
'handle rename-with-content-merge vs. add' '
472 test_setup_rename_with_content_merge_and_add AB &&
474 cd rename-with-content-merge-and-add-AB &&
478 test_must_fail git merge -s recursive B^0 >out &&
479 test_i18ngrep "CONFLICT (.*/add)" out &&
481 git ls-files -s >out &&
482 test_line_count = 2 out &&
483 git ls-files -u >out &&
484 test_line_count = 2 out &&
485 # Also, make sure both unmerged entries are for "b"
486 git ls-files -u b >out &&
487 test_line_count = 2 out &&
488 git ls-files -o >out &&
489 test_line_count = 1 out &&
491 test_path_is_missing a &&
492 test_path_is_file b &&
495 git hash-object tmp >expect &&
496 git rev-parse B:b >>expect &&
497 git rev-parse >actual \
499 test_cmp expect actual &&
501 # Test that the two-way merge in b is as expected
502 git cat-file -p :2:b >>ours &&
503 git cat-file -p :3:b >>theirs &&
505 test_must_fail git merge-file \
514 test_expect_success
'handle rename-with-content-merge vs. add, merge other way' '
515 test_setup_rename_with_content_merge_and_add BA &&
517 cd rename-with-content-merge-and-add-BA &&
524 test_must_fail git merge -s recursive A^0 >out &&
525 test_i18ngrep "CONFLICT (.*/add)" out &&
527 git ls-files -s >out &&
528 test_line_count = 2 out &&
529 git ls-files -u >out &&
530 test_line_count = 2 out &&
531 # Also, make sure both unmerged entries are for "b"
532 git ls-files -u b >out &&
533 test_line_count = 2 out &&
534 git ls-files -o >out &&
535 test_line_count = 1 out &&
537 test_path_is_missing a &&
538 test_path_is_file b &&
541 git rev-parse B:b >expect &&
542 git hash-object tmp >>expect &&
543 git rev-parse >actual \
545 test_cmp expect actual &&
547 # Test that the two-way merge in b is as expected
548 git cat-file -p :2:b >>ours &&
549 git cat-file -p :3:b >>theirs &&
551 test_must_fail git merge-file \
560 # Test for all kinds of things that can go wrong with rename/rename (2to1):
561 # Commit A: new files: a & b
562 # Commit B: rename a->c, modify b
563 # Commit C: rename b->c, modify a
565 # Merging of B & C should NOT be clean. Questions:
566 # * Both a & b should be removed by the merge; are they?
567 # * The two c's should contain modifications to a & b; do they?
568 # * The index should contain two files, both for c; does it?
569 # * The working copy should have two files, both of form c~<unique>; does it?
570 # * Nothing else should be present. Is anything?
572 test_setup_rename_rename_2to1
() {
573 git init rename-rename-2to1
&&
575 cd rename-rename-2to1
&&
577 printf "1\n2\n3\n4\n5\n" >a
&&
578 printf "5\n4\n3\n2\n1\n" >b
&&
583 git checkout
-b B A
&&
589 git checkout
-b C A
&&
597 test_expect_success
'handle rename/rename (2to1) conflict correctly' '
598 test_setup_rename_rename_2to1 &&
600 cd rename-rename-2to1 &&
604 test_must_fail git merge -s recursive C^0 >out &&
605 test_i18ngrep "CONFLICT (\(.*\)/\1)" out &&
607 git ls-files -s >out &&
608 test_line_count = 2 out &&
609 git ls-files -u >out &&
610 test_line_count = 2 out &&
611 git ls-files -u c >out &&
612 test_line_count = 2 out &&
613 git ls-files -o >out &&
614 test_line_count = 1 out &&
616 test_path_is_missing a &&
617 test_path_is_missing b &&
619 git rev-parse >expect \
621 git rev-parse >actual \
623 test_cmp expect actual &&
625 # Test that the two-way merge in new_a is as expected
626 git cat-file -p :2:c >>ours &&
627 git cat-file -p :3:c >>theirs &&
629 test_must_fail git merge-file \
634 git hash-object c >actual &&
635 git hash-object ours >expect &&
636 test_cmp expect actual
640 # Testcase setup for simple rename/rename (1to2) conflict:
641 # Commit A: new file: a
642 # Commit B: rename a->b
643 # Commit C: rename a->c
644 test_setup_rename_rename_1to2
() {
645 git init rename-rename-1to2
&&
647 cd rename-rename-1to2
&&
655 git checkout
-b B A
&&
660 git checkout
-b C A
&&
667 test_expect_success
'merge has correct working tree contents' '
668 test_setup_rename_rename_1to2 &&
670 cd rename-rename-1to2 &&
674 test_must_fail git merge -s recursive B^0 &&
676 git ls-files -s >out &&
677 test_line_count = 3 out &&
678 git ls-files -u >out &&
679 test_line_count = 3 out &&
680 git ls-files -o >out &&
681 test_line_count = 1 out &&
683 test_path_is_missing a &&
684 git rev-parse >expect \
687 git rev-parse >actual \
689 git hash-object >>actual \
691 test_cmp expect actual
695 # Testcase setup for rename/rename(1to2)/add-source conflict:
696 # Commit A: new file: a
697 # Commit B: rename a->b
698 # Commit C: rename a->c, add completely different a
700 # Merging of B & C should NOT be clean; there's a rename/rename conflict
702 test_setup_rename_rename_1to2_add_source_1
() {
703 git init rename-rename-1to2-add-source-1
&&
705 cd rename-rename-1to2-add-source-1
&&
707 printf "1\n2\n3\n4\n5\n6\n7\n" >a
&&
712 git checkout
-b B A
&&
716 git checkout
-b C A
&&
718 echo something completely different
>a
&&
724 test_expect_failure
'detect conflict with rename/rename(1to2)/add-source merge' '
725 test_setup_rename_rename_1to2_add_source_1 &&
727 cd rename-rename-1to2-add-source-1 &&
731 test_must_fail git merge -s recursive C^0 &&
733 git ls-files -s >out &&
734 test_line_count = 4 out &&
735 git ls-files -o >out &&
736 test_line_count = 1 out &&
738 git rev-parse >expect \
740 git rev-parse >actual \
741 :3:a :1:a :2:b :3:c &&
742 test_cmp expect actual &&
744 test_path_is_file a &&
745 test_path_is_file b &&
750 test_setup_rename_rename_1to2_add_source_2
() {
751 git init rename-rename-1to2-add-source-2
&&
753 cd rename-rename-1to2-add-source-2
&&
758 git commit
-m base
&&
761 git checkout
-b B A
&&
766 git checkout
-b C A
&&
768 echo important-info
>a
&&
775 test_expect_failure
'rename/rename/add-source still tracks new a file' '
776 test_setup_rename_rename_1to2_add_source_2 &&
778 cd rename-rename-1to2-add-source-2 &&
781 git merge -s recursive B^0 &&
783 git ls-files -s >out &&
784 test_line_count = 2 out &&
785 git ls-files -o >out &&
786 test_line_count = 1 out &&
788 git rev-parse >expect \
790 git rev-parse >actual \
792 test_cmp expect actual
796 test_setup_rename_rename_1to2_add_dest
() {
797 git init rename-rename-1to2-add-dest
&&
799 cd rename-rename-1to2-add-dest
&&
804 git commit
-m base
&&
807 git checkout
-b B A
&&
809 echo precious-data
>c
&&
814 git checkout
-b C A
&&
816 echo important-info
>b
&&
823 test_expect_success
'rename/rename/add-dest merge still knows about conflicting file versions' '
824 test_setup_rename_rename_1to2_add_dest &&
826 cd rename-rename-1to2-add-dest &&
829 test_must_fail git merge -s recursive B^0 &&
831 git ls-files -s >out &&
832 test_line_count = 5 out &&
833 git ls-files -u b >out &&
834 test_line_count = 2 out &&
835 git ls-files -u c >out &&
836 test_line_count = 2 out &&
837 git ls-files -o >out &&
838 test_line_count = 1 out &&
840 git rev-parse >expect \
841 A:a C:b B:b C:c B:c &&
842 git rev-parse >actual \
843 :1:a :2:b :3:b :2:c :3:c &&
844 test_cmp expect actual &&
846 # Record some contents for re-doing merges
847 git cat-file -p A:a >stuff &&
848 git cat-file -p C:b >important_info &&
849 git cat-file -p B:c >precious_data &&
852 # Test the merge in b
853 test_must_fail git merge-file \
857 important_info empty stuff &&
858 test_cmp important_info b &&
860 # Test the merge in c
861 test_must_fail git merge-file \
865 stuff empty precious_data &&
870 # Testcase rad, rename/add/delete
872 # Commit A: rm foo, add different bar
873 # Commit B: rename foo->bar
874 # Expected: CONFLICT (rename/add/delete), two-way merged bar
880 echo "original file" >foo
&&
882 git commit
-m "original" &&
890 echo "different file" >bar
&&
892 git commit
-m "Remove foo, add bar" &&
896 git commit
-m "rename foo to bar"
900 test_expect_merge_algorithm failure success
'rad-check: rename/add/delete conflict' '
906 test_must_fail git merge -s recursive A^0 >out 2>err &&
908 # Instead of requiring the output to contain one combined line
909 # CONFLICT (rename/add/delete)
910 # or perhaps two lines:
911 # CONFLICT (rename/add): new file collides with rename target
912 # CONFLICT (rename/delete): rename source removed on other side
913 # and instead of requiring "rename/add" instead of "add/add",
914 # be flexible in the type of console output message(s) reported
915 # for this particular case; we will be more stringent about the
916 # contents of the index and working directory.
917 test_i18ngrep "CONFLICT (.*/add)" out &&
918 test_i18ngrep "CONFLICT (rename.*/delete)" out &&
919 test_must_be_empty err &&
921 git ls-files -s >file_count &&
922 test_line_count = 2 file_count &&
923 git ls-files -u >file_count &&
924 test_line_count = 2 file_count &&
925 git ls-files -o >file_count &&
926 test_line_count = 3 file_count &&
928 git rev-parse >actual \
930 git rev-parse >expect \
933 test_path_is_missing foo &&
934 # bar should have two-way merged contents of the different
935 # versions of bar; check that content from both sides is
942 # Testcase rrdd, rename/rename(2to1)/delete/delete
944 # Commit A: rename foo->baz, rm bar
945 # Commit B: rename bar->baz, rm foo
946 # Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz
964 git commit
-m "Rename foo, remove bar" &&
969 git commit
-m "Rename bar, remove foo"
973 test_expect_merge_algorithm failure success
'rrdd-check: rename/rename(2to1)/delete/delete conflict' '
979 test_must_fail git merge -s recursive B^0 >out 2>err &&
981 # Instead of requiring the output to contain one combined line
982 # CONFLICT (rename/rename/delete/delete)
983 # or perhaps two lines:
984 # CONFLICT (rename/rename): ...
985 # CONFLICT (rename/delete): info about pair 1
986 # CONFLICT (rename/delete): info about pair 2
987 # and instead of requiring "rename/rename" instead of "add/add",
988 # be flexible in the type of console output message(s) reported
989 # for this particular case; we will be more stringent about the
990 # contents of the index and working directory.
991 test_i18ngrep "CONFLICT (\(.*\)/\1)" out &&
992 test_i18ngrep "CONFLICT (rename.*delete)" out &&
993 test_must_be_empty err &&
995 git ls-files -s >file_count &&
996 test_line_count = 2 file_count &&
997 git ls-files -u >file_count &&
998 test_line_count = 2 file_count &&
999 git ls-files -o >file_count &&
1000 test_line_count = 3 file_count &&
1002 git rev-parse >actual \
1004 git rev-parse >expect \
1007 test_path_is_missing foo &&
1008 test_path_is_missing bar &&
1009 # baz should have two-way merged contents of the original
1010 # contents of foo and bar; check that content from both sides
1017 # Testcase mod6, chains of rename/rename(1to2) and rename/rename(2to1)
1018 # Commit O: one, three, five
1019 # Commit A: one->two, three->four, five->six
1020 # Commit B: one->six, three->two, five->four
1021 # Expected: six CONFLICT(rename/rename) messages, each path in two of the
1022 # multi-way merged contents found in two, four, six
1024 test_setup_mod6
() {
1028 test_seq
11 19 >one
&&
1029 test_seq
31 39 >three
&&
1030 test_seq
51 59 >five
&&
1033 git commit
-m "O" &&
1040 test_seq
10 19 >one
&&
1042 git add one three
&&
1044 git
mv three four
&&
1047 git commit
-m "A" &&
1051 echo forty
>>three
&&
1053 git add one three five
&&
1062 test_expect_merge_algorithm failure success
'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '
1069 test_must_fail git merge -s recursive B^0 >out 2>err &&
1071 test_i18ngrep "CONFLICT (rename/rename)" out &&
1072 test_must_be_empty err &&
1074 git ls-files -s >file_count &&
1075 test_line_count = 9 file_count &&
1076 git ls-files -u >file_count &&
1077 test_line_count = 9 file_count &&
1078 git ls-files -o >file_count &&
1079 test_line_count = 3 file_count &&
1081 test_seq 10 20 >merged-one &&
1082 test_seq 51 60 >merged-five &&
1083 # Determine what the merge of three would give us.
1084 test_seq 31 39 >three-base &&
1085 test_seq 31 40 >three-side-A &&
1086 test_seq 31 39 >three-side-B &&
1087 echo forty >>three-side-B &&
1088 test_must_fail git merge-file \
1092 three-side-A three-base three-side-B &&
1093 sed -e "s/^\([<=>]\)/\1\1/" three-side-A >merged-three &&
1095 # Verify the index is as expected
1096 git rev-parse >actual \
1100 git hash-object >expect \
1101 merged-one merged-three \
1102 merged-three merged-five \
1103 merged-five merged-one &&
1104 test_cmp expect actual &&
1106 git cat-file -p :2:two >expect &&
1107 git cat-file -p :3:two >other &&
1109 test_must_fail git merge-file \
1110 -L "HEAD" -L "" -L "B^0" \
1111 expect empty other &&
1112 test_cmp expect two &&
1114 git cat-file -p :2:four >expect &&
1115 git cat-file -p :3:four >other &&
1116 test_must_fail git merge-file \
1117 -L "HEAD" -L "" -L "B^0" \
1118 expect empty other &&
1119 test_cmp expect four &&
1121 git cat-file -p :2:six >expect &&
1122 git cat-file -p :3:six >other &&
1123 test_must_fail git merge-file \
1124 -L "HEAD" -L "" -L "B^0" \
1125 expect empty other &&
1130 test_conflicts_with_adds_and_renames
() {
1142 # Both L and R have files named 'three' which collide. Each of
1143 # the colliding files could have been involved in a rename, in
1144 # which case there was a file named 'one' or 'two' that was
1145 # modified on the opposite side of history and renamed into the
1146 # collision on this side of history.
1149 # 1) The index should contain both a stage 2 and stage 3 entry
1150 # for the colliding file. Does it?
1151 # 2) When renames are involved, the content merges are clean, so
1152 # the index should reflect the content merges, not merely the
1153 # version of the colliding file from the prior commit. Does
1155 # 3) There should be a file in the worktree named 'three'
1156 # containing the two-way merged contents of the content-merged
1157 # versions of 'three' from each of the two colliding
1158 # files. Is it present?
1159 # 4) There should not be any three~* files in the working
1161 test_setup_collision_conflict
() {
1162 git init simple_
${sideL}_
${sideR} &&
1164 cd simple_
${sideL}_
${sideR} &&
1166 # Create some related files now
1167 for i
in $
(test_seq
1 10)
1169 echo Random base content line
$i
1171 cp file_v1 file_v2
&&
1172 echo modification
>>file_v2
&&
1174 cp file_v1 file_v3
&&
1175 echo more stuff
>>file_v3
&&
1176 cp file_v3 file_v4
&&
1177 echo yet
more stuff
>>file_v4
&&
1179 # Use a tag to record both these files for simple
1180 # access, and clean out these untracked files
1181 git tag file_v1 $
(git hash-object
-w file_v1
) &&
1182 git tag file_v2 $
(git hash-object
-w file_v2
) &&
1183 git tag file_v3 $
(git hash-object
-w file_v3
) &&
1184 git tag file_v4 $
(git hash-object
-w file_v4
) &&
1187 # Setup original commit (or merge-base), consisting of
1188 # files named "one" and "two" if renames were involved.
1189 touch irrelevant_file
&&
1190 git add irrelevant_file
&&
1191 if [ $sideL = "rename" ]
1193 git show file_v1
>one
&&
1196 if [ $sideR = "rename" ]
1198 git show file_v3
>two
&&
1201 test_tick
&& git commit
-m initial
&&
1206 # Handle the left side
1208 if [ $sideL = "rename" ]
1212 git show file_v2
>three
&&
1215 if [ $sideR = "rename" ]
1217 git show file_v4
>two
&&
1220 test_tick
&& git commit
-m L
&&
1222 # Handle the right side
1224 if [ $sideL = "rename" ]
1226 git show file_v2
>one
&&
1229 if [ $sideR = "rename" ]
1233 git show file_v4
>three
&&
1236 test_tick
&& git commit
-m R
1240 test_expect_success
"check simple $sideL/$sideR conflict" '
1241 test_setup_collision_conflict &&
1243 cd simple_${sideL}_${sideR} &&
1247 # Merge must fail; there is a conflict
1248 test_must_fail git merge -s recursive R^0 &&
1250 # Make sure the index has the right number of entries
1251 git ls-files -s >out &&
1252 test_line_count = 3 out &&
1253 git ls-files -u >out &&
1254 test_line_count = 2 out &&
1255 # Ensure we have the correct number of untracked files
1256 git ls-files -o >out &&
1257 test_line_count = 1 out &&
1259 # Nothing should have touched irrelevant_file
1260 git rev-parse >actual \
1261 :0:irrelevant_file \
1264 git rev-parse >expected \
1265 main:irrelevant_file \
1268 test_cmp expected actual &&
1270 # Make sure we have the correct merged contents for
1272 git show file_v1 >expected &&
1273 cat <<-\EOF >>expected &&
1282 test_cmp expected three
1287 test_conflicts_with_adds_and_renames rename rename
1288 test_conflicts_with_adds_and_renames rename add
1289 test_conflicts_with_adds_and_renames add rename
1290 test_conflicts_with_adds_and_renames add add
1300 # main has two files, named 'one' and 'two'.
1301 # branches L and R both modify 'one', in conflicting ways.
1302 # branches L and R both modify 'two', in conflicting ways.
1303 # branch L also renames 'one' to 'three'.
1304 # branch R also renames 'two' to 'three'.
1306 # So, we have four different conflicting files that all end up at path
1308 test_setup_nested_conflicts_from_rename_rename
() {
1309 git init nested_conflicts_from_rename_rename
&&
1311 cd nested_conflicts_from_rename_rename
&&
1313 # Create some related files now
1314 for i
in $
(test_seq
1 10)
1316 echo Random base content line
$i
1319 cp file_v1 file_v2
&&
1320 cp file_v1 file_v3
&&
1321 cp file_v1 file_v4
&&
1322 cp file_v1 file_v5
&&
1323 cp file_v1 file_v6
&&
1325 echo one
>>file_v1
&&
1326 echo uno
>>file_v2
&&
1327 echo eins
>>file_v3
&&
1329 echo two
>>file_v4
&&
1330 echo dos
>>file_v5
&&
1331 echo zwei
>>file_v6
&&
1333 # Setup original commit (or merge-base), consisting of
1334 # files named "one" and "two".
1338 test_tick
&& git commit
-m english
&&
1343 # Handle the left side
1346 mv -f file_v2 three
&&
1347 mv -f file_v5 two
&&
1348 git add two three
&&
1349 test_tick
&& git commit
-m spanish
&&
1351 # Handle the right side
1354 mv -f file_v3 one
&&
1355 mv -f file_v6 three
&&
1356 git add one three
&&
1357 test_tick
&& git commit
-m german
1361 test_expect_success
'check nested conflicts from rename/rename(2to1)' '
1362 test_setup_nested_conflicts_from_rename_rename &&
1364 cd nested_conflicts_from_rename_rename &&
1368 # Merge must fail; there is a conflict
1369 test_must_fail git merge -s recursive R^0 &&
1371 # Make sure the index has the right number of entries
1372 git ls-files -s >out &&
1373 test_line_count = 2 out &&
1374 git ls-files -u >out &&
1375 test_line_count = 2 out &&
1376 # Ensure we have the correct number of untracked files
1377 git ls-files -o >out &&
1378 test_line_count = 1 out &&
1380 # Compare :2:three to expected values
1381 git cat-file -p main:one >base &&
1382 git cat-file -p L:three >ours &&
1383 git cat-file -p R:one >theirs &&
1384 test_must_fail git merge-file \
1385 -L "HEAD:three" -L "" -L "R^0:one" \
1387 sed -e "s/^\([<=>]\)/\1\1/" ours >L-three &&
1388 git cat-file -p :2:three >expect &&
1389 test_cmp expect L-three &&
1391 # Compare :2:three to expected values
1392 git cat-file -p main:two >base &&
1393 git cat-file -p L:two >ours &&
1394 git cat-file -p R:three >theirs &&
1395 test_must_fail git merge-file \
1396 -L "HEAD:two" -L "" -L "R^0:three" \
1398 sed -e "s/^\([<=>]\)/\1\1/" ours >R-three &&
1399 git cat-file -p :3:three >expect &&
1400 test_cmp expect R-three &&
1402 # Compare three to expected contents
1404 test_must_fail git merge-file \
1405 -L "HEAD" -L "" -L "R^0" \
1406 L-three empty R-three &&
1407 test_cmp three L-three
1411 # Testcase rename/rename(1to2) of a binary file
1415 # Expected: CONFLICT(rename/rename) message, three unstaged entries in the
1416 # index, and contents of orig-[AB] at path orig-[AB]
1417 test_setup_rename_rename_1_to_2_binary
() {
1418 git init rename_rename_1_to_2_binary
&&
1420 cd rename_rename_1_to_2_binary
&&
1422 echo '* binary' >.gitattributes
&&
1423 git add .gitattributes
&&
1425 test_seq
1 10 >orig
&&
1427 git commit
-m orig
&&
1433 git
mv orig orig-A
&&
1434 test_seq
1 11 >orig-A
&&
1436 git commit
-m orig-A
&&
1439 git
mv orig orig-B
&&
1440 test_seq
0 10 >orig-B
&&
1442 git commit
-m orig-B
1447 test_expect_success
'rename/rename(1to2) with a binary file' '
1448 test_setup_rename_rename_1_to_2_binary &&
1450 cd rename_rename_1_to_2_binary &&
1454 test_must_fail git merge -s recursive B^0 &&
1456 # Make sure the index has the right number of entries
1457 git ls-files -s >actual &&
1458 test_line_count = 4 actual &&
1460 git rev-parse A:orig-A B:orig-B >expect &&
1461 git hash-object orig-A orig-B >actual &&
1462 test_cmp expect actual