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
7 . "$TEST_DIRECTORY"/lib-merge.sh
9 test_setup_rename_delete_untracked () {
10 test_create_repo rename-delete-untracked &&
12 cd rename-delete-untracked &&
14 echo "A pretty inscription" >ring &&
17 git commit -m beginning &&
20 git checkout -b rename-the-ring &&
21 git mv ring one-ring-to-rule-them-all &&
23 git commit -m fullname &&
25 git checkout people &&
30 git commit -m track-people-instead-of-objects &&
31 echo "Myyy PRECIOUSSS" >ring
35 test_expect_success "Does git preserve Gollum's precious artifact?" '
36 test_setup_rename_delete_untracked &&
38 cd rename-delete-untracked &&
40 test_must_fail git merge -s recursive rename-the-ring &&
42 # Make sure git did not delete an untracked file
43 test_path_is_file ring
47 # Testcase setup for rename/modify/add-source:
48 # Commit A: new file: a
49 # Commit B: modify a slightly
50 # Commit C: rename a->b, add completely different a
52 # We should be able to merge B & C cleanly
54 test_setup_rename_modify_add_source () {
55 test_create_repo rename-modify-add-source &&
57 cd rename-modify-add-source &&
59 printf "1\n2\n3\n4\n5\n6\n7\n" >a &&
64 git checkout -b B A &&
69 git checkout -b C A &&
71 echo something completely different >a &&
77 test_expect_failure 'rename/modify/add-source conflict resolvable' '
78 test_setup_rename_modify_add_source &&
80 cd rename-modify-add-source &&
84 git merge -s recursive C^0 &&
86 git rev-parse >expect \
88 git rev-parse >actual \
90 test_cmp expect actual
94 test_setup_break_detection_1 () {
95 test_create_repo break-detection-1 &&
97 cd break-detection-1 &&
99 printf "1\n2\n3\n4\n5\n" >a &&
105 git checkout -b B A &&
107 echo "Completely different content" >a &&
111 git checkout -b C A &&
118 test_expect_failure 'conflict caused if rename not detected' '
119 test_setup_break_detection_1 &&
121 cd break-detection-1 &&
123 git checkout -q C^0 &&
124 git merge -s recursive B^0 &&
126 git ls-files -s >out &&
127 test_line_count = 3 out &&
128 git ls-files -u >out &&
129 test_line_count = 0 out &&
130 git ls-files -o >out &&
131 test_line_count = 1 out &&
133 test_line_count = 6 c &&
134 git rev-parse >expect \
136 git rev-parse >actual \
138 test_cmp expect actual
142 test_setup_break_detection_2 () {
143 test_create_repo break-detection-2 &&
145 cd break-detection-2 &&
147 printf "1\n2\n3\n4\n5\n" >a &&
153 git checkout -b D A &&
157 echo "Completely different content" >a &&
161 git checkout -b E A &&
163 echo "Completely different content" >>a &&
169 test_expect_failure 'missed conflict if rename not detected' '
170 test_setup_break_detection_2 &&
172 cd break-detection-2 &&
174 git checkout -q E^0 &&
175 test_must_fail git merge -s recursive D^0
179 # Tests for undetected rename/add-source causing a file to erroneously be
180 # deleted (and for mishandled rename/rename(1to1) causing the same issue).
182 # This test uses a rename/rename(1to1)+add-source conflict (1to1 means the
183 # same file is renamed on both sides to the same thing; it should trigger
184 # the 1to2 logic, which it would do if the add-source didn't cause issues
185 # for git's rename detection):
186 # Commit A: new file: a
187 # Commit B: rename a->b
188 # Commit C: rename a->b, add unrelated a
190 test_setup_break_detection_3 () {
191 test_create_repo break-detection-3 &&
193 cd break-detection-3 &&
195 printf "1\n2\n3\n4\n5\n" >a &&
200 git checkout -b B A &&
204 git checkout -b C A &&
212 test_expect_failure 'detect rename/add-source and preserve all data' '
213 test_setup_break_detection_3 &&
215 cd break-detection-3 &&
219 git merge -s recursive C^0 &&
221 git ls-files -s >out &&
222 test_line_count = 2 out &&
223 git ls-files -u >out &&
224 test_line_count = 2 out &&
225 git ls-files -o >out &&
226 test_line_count = 1 out &&
228 test_path_is_file a &&
229 test_path_is_file b &&
231 git rev-parse >expect \
233 git rev-parse >actual \
235 test_cmp expect actual
239 test_expect_failure 'detect rename/add-source and preserve all data, merge other way' '
240 test_setup_break_detection_3 &&
242 cd break-detection-3 &&
246 git merge -s recursive B^0 &&
248 git ls-files -s >out &&
249 test_line_count = 2 out &&
250 git ls-files -u >out &&
251 test_line_count = 2 out &&
252 git ls-files -o >out &&
253 test_line_count = 1 out &&
255 test_path_is_file a &&
256 test_path_is_file b &&
258 git rev-parse >expect \
260 git rev-parse >actual \
262 test_cmp expect actual
266 test_setup_rename_directory () {
267 test_create_repo rename-directory-$1 &&
269 cd rename-directory-$1 &&
271 printf "1\n2\n3\n4\n5\n6\n" >file &&
274 git commit -m base &&
277 git checkout -b right &&
280 echo junk >newfile/realfile &&
281 git add file newfile/realfile &&
283 git commit -m right &&
285 git checkout -b left-conflict base &&
288 git mv file newfile &&
290 git commit -m left &&
292 git checkout -b left-clean base &&
294 cat file >>newfile &&
302 test_expect_success 'rename/directory conflict + clean content merge' '
303 test_setup_rename_directory 1a &&
305 cd rename-directory-1a &&
307 git checkout left-clean^0 &&
309 test_must_fail git merge -s recursive right^0 &&
311 git ls-files -s >out &&
312 test_line_count = 2 out &&
313 git ls-files -u >out &&
314 test_line_count = 1 out &&
315 git ls-files -o >out &&
316 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
318 test_line_count = 1 out
320 test_line_count = 2 out
324 git cat-file -p base:file >>expect &&
326 test_cmp expect newfile~HEAD &&
328 test_path_is_file newfile/realfile &&
329 test_path_is_file newfile~HEAD
333 test_expect_success 'rename/directory conflict + content merge conflict' '
334 test_setup_rename_directory 1b &&
336 cd rename-directory-1b &&
341 git checkout left-conflict^0 &&
343 test_must_fail git merge -s recursive right^0 &&
345 git ls-files -s >out &&
346 test_line_count = 4 out &&
347 git ls-files -u >out &&
348 test_line_count = 3 out &&
349 git ls-files -o >out &&
350 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
352 test_line_count = 1 out
354 test_line_count = 2 out
357 git cat-file -p left-conflict:newfile >left &&
358 git cat-file -p base:file >base &&
359 git cat-file -p right:file >right &&
360 test_must_fail git merge-file \
365 test_cmp left newfile~HEAD &&
367 git rev-parse >expect \
368 base:file left-conflict:newfile right:file &&
369 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
371 git rev-parse >actual \
372 :1:newfile~HEAD :2:newfile~HEAD :3:newfile~HEAD
374 git rev-parse >actual \
375 :1:newfile :2:newfile :3:newfile
377 test_cmp expect actual &&
379 test_path_is_file newfile/realfile &&
380 test_path_is_file newfile~HEAD
384 test_setup_rename_directory_2 () {
385 test_create_repo rename-directory-2 &&
387 cd rename-directory-2 &&
390 printf "1\n2\n3\n4\n5\n6\n" >sub/file &&
393 git commit -m base &&
396 git checkout -b right &&
400 git commit -m right &&
402 git checkout -b left base &&
404 cat sub/file >>newfile &&
413 test_expect_success 'disappearing dir in rename/directory conflict handled' '
414 test_setup_rename_directory_2 &&
416 cd rename-directory-2 &&
418 git checkout left^0 &&
420 git merge -s recursive right^0 &&
422 git ls-files -s >out &&
423 test_line_count = 1 out &&
424 git ls-files -u >out &&
425 test_line_count = 0 out &&
426 git ls-files -o >out &&
427 test_line_count = 1 out &&
430 git cat-file -p base:sub/file >>expect &&
432 test_cmp expect sub &&
434 test_path_is_file sub
438 # Test for basic rename/add-dest conflict, with rename needing content merge:
440 # Commit A: rename a->b, modifying b too
441 # Commit B: modify a, add different b
443 test_setup_rename_with_content_merge_and_add () {
444 test_create_repo rename-with-content-merge-and-add-$1 &&
446 cd rename-with-content-merge-and-add-$1 &&
453 git checkout -b A O &&
459 git checkout -b B O &&
461 echo hello world >b &&
467 test_expect_success 'handle rename-with-content-merge vs. add' '
468 test_setup_rename_with_content_merge_and_add AB &&
470 cd rename-with-content-merge-and-add-AB &&
474 test_must_fail git merge -s recursive B^0 >out &&
475 test_i18ngrep "CONFLICT (.*/add)" out &&
477 git ls-files -s >out &&
478 test_line_count = 2 out &&
479 git ls-files -u >out &&
480 test_line_count = 2 out &&
481 # Also, make sure both unmerged entries are for "b"
482 git ls-files -u b >out &&
483 test_line_count = 2 out &&
484 git ls-files -o >out &&
485 test_line_count = 1 out &&
487 test_path_is_missing a &&
488 test_path_is_file b &&
491 git hash-object tmp >expect &&
492 git rev-parse B:b >>expect &&
493 git rev-parse >actual \
495 test_cmp expect actual &&
497 # Test that the two-way merge in b is as expected
498 git cat-file -p :2:b >>ours &&
499 git cat-file -p :3:b >>theirs &&
501 test_must_fail git merge-file \
510 test_expect_success 'handle rename-with-content-merge vs. add, merge other way' '
511 test_setup_rename_with_content_merge_and_add BA &&
513 cd rename-with-content-merge-and-add-BA &&
520 test_must_fail git merge -s recursive A^0 >out &&
521 test_i18ngrep "CONFLICT (.*/add)" out &&
523 git ls-files -s >out &&
524 test_line_count = 2 out &&
525 git ls-files -u >out &&
526 test_line_count = 2 out &&
527 # Also, make sure both unmerged entries are for "b"
528 git ls-files -u b >out &&
529 test_line_count = 2 out &&
530 git ls-files -o >out &&
531 test_line_count = 1 out &&
533 test_path_is_missing a &&
534 test_path_is_file b &&
537 git rev-parse B:b >expect &&
538 git hash-object tmp >>expect &&
539 git rev-parse >actual \
541 test_cmp expect actual &&
543 # Test that the two-way merge in b is as expected
544 git cat-file -p :2:b >>ours &&
545 git cat-file -p :3:b >>theirs &&
547 test_must_fail git merge-file \
556 # Test for all kinds of things that can go wrong with rename/rename (2to1):
557 # Commit A: new files: a & b
558 # Commit B: rename a->c, modify b
559 # Commit C: rename b->c, modify a
561 # Merging of B & C should NOT be clean. Questions:
562 # * Both a & b should be removed by the merge; are they?
563 # * The two c's should contain modifications to a & b; do they?
564 # * The index should contain two files, both for c; does it?
565 # * The working copy should have two files, both of form c~<unique>; does it?
566 # * Nothing else should be present. Is anything?
568 test_setup_rename_rename_2to1 () {
569 test_create_repo rename-rename-2to1 &&
571 cd rename-rename-2to1 &&
573 printf "1\n2\n3\n4\n5\n" >a &&
574 printf "5\n4\n3\n2\n1\n" >b &&
579 git checkout -b B A &&
585 git checkout -b C A &&
593 test_expect_success 'handle rename/rename (2to1) conflict correctly' '
594 test_setup_rename_rename_2to1 &&
596 cd rename-rename-2to1 &&
600 test_must_fail git merge -s recursive C^0 >out &&
601 test_i18ngrep "CONFLICT (\(.*\)/\1)" out &&
603 git ls-files -s >out &&
604 test_line_count = 2 out &&
605 git ls-files -u >out &&
606 test_line_count = 2 out &&
607 git ls-files -u c >out &&
608 test_line_count = 2 out &&
609 git ls-files -o >out &&
610 test_line_count = 1 out &&
612 test_path_is_missing a &&
613 test_path_is_missing b &&
615 git rev-parse >expect \
617 git rev-parse >actual \
619 test_cmp expect actual &&
621 # Test that the two-way merge in new_a is as expected
622 git cat-file -p :2:c >>ours &&
623 git cat-file -p :3:c >>theirs &&
625 test_must_fail git merge-file \
630 git hash-object c >actual &&
631 git hash-object ours >expect &&
632 test_cmp expect actual
636 # Testcase setup for simple rename/rename (1to2) conflict:
637 # Commit A: new file: a
638 # Commit B: rename a->b
639 # Commit C: rename a->c
640 test_setup_rename_rename_1to2 () {
641 test_create_repo rename-rename-1to2 &&
643 cd rename-rename-1to2 &&
651 git checkout -b B A &&
656 git checkout -b C A &&
663 test_expect_success 'merge has correct working tree contents' '
664 test_setup_rename_rename_1to2 &&
666 cd rename-rename-1to2 &&
670 test_must_fail git merge -s recursive B^0 &&
672 git ls-files -s >out &&
673 test_line_count = 3 out &&
674 git ls-files -u >out &&
675 test_line_count = 3 out &&
676 git ls-files -o >out &&
677 test_line_count = 1 out &&
679 test_path_is_missing a &&
680 git rev-parse >expect \
683 git rev-parse >actual \
685 git hash-object >>actual \
687 test_cmp expect actual
691 # Testcase setup for rename/rename(1to2)/add-source conflict:
692 # Commit A: new file: a
693 # Commit B: rename a->b
694 # Commit C: rename a->c, add completely different a
696 # Merging of B & C should NOT be clean; there's a rename/rename conflict
698 test_setup_rename_rename_1to2_add_source_1 () {
699 test_create_repo rename-rename-1to2-add-source-1 &&
701 cd rename-rename-1to2-add-source-1 &&
703 printf "1\n2\n3\n4\n5\n6\n7\n" >a &&
708 git checkout -b B A &&
712 git checkout -b C A &&
714 echo something completely different >a &&
720 test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge' '
721 test_setup_rename_rename_1to2_add_source_1 &&
723 cd rename-rename-1to2-add-source-1 &&
727 test_must_fail git merge -s recursive C^0 &&
729 git ls-files -s >out &&
730 test_line_count = 4 out &&
731 git ls-files -o >out &&
732 test_line_count = 1 out &&
734 git rev-parse >expect \
736 git rev-parse >actual \
737 :3:a :1:a :2:b :3:c &&
738 test_cmp expect actual &&
740 test_path_is_file a &&
741 test_path_is_file b &&
746 test_setup_rename_rename_1to2_add_source_2 () {
747 test_create_repo rename-rename-1to2-add-source-2 &&
749 cd rename-rename-1to2-add-source-2 &&
754 git commit -m base &&
757 git checkout -b B A &&
762 git checkout -b C A &&
764 echo important-info >a &&
771 test_expect_failure 'rename/rename/add-source still tracks new a file' '
772 test_setup_rename_rename_1to2_add_source_2 &&
774 cd rename-rename-1to2-add-source-2 &&
777 git merge -s recursive B^0 &&
779 git ls-files -s >out &&
780 test_line_count = 2 out &&
781 git ls-files -o >out &&
782 test_line_count = 1 out &&
784 git rev-parse >expect \
786 git rev-parse >actual \
788 test_cmp expect actual
792 test_setup_rename_rename_1to2_add_dest () {
793 test_create_repo rename-rename-1to2-add-dest &&
795 cd rename-rename-1to2-add-dest &&
800 git commit -m base &&
803 git checkout -b B A &&
805 echo precious-data >c &&
810 git checkout -b C A &&
812 echo important-info >b &&
819 test_expect_success 'rename/rename/add-dest merge still knows about conflicting file versions' '
820 test_setup_rename_rename_1to2_add_dest &&
822 cd rename-rename-1to2-add-dest &&
825 test_must_fail git merge -s recursive B^0 &&
827 git ls-files -s >out &&
828 test_line_count = 5 out &&
829 git ls-files -u b >out &&
830 test_line_count = 2 out &&
831 git ls-files -u c >out &&
832 test_line_count = 2 out &&
833 git ls-files -o >out &&
834 test_line_count = 1 out &&
836 git rev-parse >expect \
837 A:a C:b B:b C:c B:c &&
838 git rev-parse >actual \
839 :1:a :2:b :3:b :2:c :3:c &&
840 test_cmp expect actual &&
842 # Record some contents for re-doing merges
843 git cat-file -p A:a >stuff &&
844 git cat-file -p C:b >important_info &&
845 git cat-file -p B:c >precious_data &&
848 # Test the merge in b
849 test_must_fail git merge-file \
853 important_info empty stuff &&
854 test_cmp important_info b &&
856 # Test the merge in c
857 test_must_fail git merge-file \
861 stuff empty precious_data &&
866 # Testcase rad, rename/add/delete
868 # Commit A: rm foo, add different bar
869 # Commit B: rename foo->bar
870 # Expected: CONFLICT (rename/add/delete), two-way merged bar
873 test_create_repo rad &&
876 echo "original file" >foo &&
878 git commit -m "original" &&
886 echo "different file" >bar &&
888 git commit -m "Remove foo, add bar" &&
892 git commit -m "rename foo to bar"
896 test_expect_merge_algorithm failure success 'rad-check: rename/add/delete conflict' '
902 test_must_fail git merge -s recursive A^0 >out 2>err &&
904 # Instead of requiring the output to contain one combined line
905 # CONFLICT (rename/add/delete)
906 # or perhaps two lines:
907 # CONFLICT (rename/add): new file collides with rename target
908 # CONFLICT (rename/delete): rename source removed on other side
909 # and instead of requiring "rename/add" instead of "add/add",
910 # be flexible in the type of console output message(s) reported
911 # for this particular case; we will be more stringent about the
912 # contents of the index and working directory.
913 test_i18ngrep "CONFLICT (.*/add)" out &&
914 test_i18ngrep "CONFLICT (rename.*/delete)" out &&
915 test_must_be_empty err &&
917 git ls-files -s >file_count &&
918 test_line_count = 2 file_count &&
919 git ls-files -u >file_count &&
920 test_line_count = 2 file_count &&
921 git ls-files -o >file_count &&
922 test_line_count = 3 file_count &&
924 git rev-parse >actual \
926 git rev-parse >expect \
929 test_path_is_missing foo &&
930 # bar should have two-way merged contents of the different
931 # versions of bar; check that content from both sides is
938 # Testcase rrdd, rename/rename(2to1)/delete/delete
940 # Commit A: rename foo->baz, rm bar
941 # Commit B: rename bar->baz, rm foo
942 # Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz
945 test_create_repo rrdd &&
960 git commit -m "Rename foo, remove bar" &&
965 git commit -m "Rename bar, remove foo"
969 test_expect_merge_algorithm failure success 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '
975 test_must_fail git merge -s recursive B^0 >out 2>err &&
977 # Instead of requiring the output to contain one combined line
978 # CONFLICT (rename/rename/delete/delete)
979 # or perhaps two lines:
980 # CONFLICT (rename/rename): ...
981 # CONFLICT (rename/delete): info about pair 1
982 # CONFLICT (rename/delete): info about pair 2
983 # and instead of requiring "rename/rename" instead of "add/add",
984 # be flexible in the type of console output message(s) reported
985 # for this particular case; we will be more stringent about the
986 # contents of the index and working directory.
987 test_i18ngrep "CONFLICT (\(.*\)/\1)" out &&
988 test_i18ngrep "CONFLICT (rename.*delete)" out &&
989 test_must_be_empty err &&
991 git ls-files -s >file_count &&
992 test_line_count = 2 file_count &&
993 git ls-files -u >file_count &&
994 test_line_count = 2 file_count &&
995 git ls-files -o >file_count &&
996 test_line_count = 3 file_count &&
998 git rev-parse >actual \
1000 git rev-parse >expect \
1003 test_path_is_missing foo &&
1004 test_path_is_missing bar &&
1005 # baz should have two-way merged contents of the original
1006 # contents of foo and bar; check that content from both sides
1013 # Testcase mod6, chains of rename/rename(1to2) and rename/rename(2to1)
1014 # Commit O: one, three, five
1015 # Commit A: one->two, three->four, five->six
1016 # Commit B: one->six, three->two, five->four
1017 # Expected: six CONFLICT(rename/rename) messages, each path in two of the
1018 # multi-way merged contents found in two, four, six
1020 test_setup_mod6 () {
1021 test_create_repo mod6 &&
1024 test_seq 11 19 >one &&
1025 test_seq 31 39 >three &&
1026 test_seq 51 59 >five &&
1029 git commit -m "O" &&
1036 test_seq 10 19 >one &&
1038 git add one three &&
1040 git mv three four &&
1043 git commit -m "A" &&
1047 echo forty >>three &&
1049 git add one three five &&
1058 test_expect_merge_algorithm failure success 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '
1065 test_must_fail git merge -s recursive B^0 >out 2>err &&
1067 test_i18ngrep "CONFLICT (rename/rename)" out &&
1068 test_must_be_empty err &&
1070 git ls-files -s >file_count &&
1071 test_line_count = 9 file_count &&
1072 git ls-files -u >file_count &&
1073 test_line_count = 9 file_count &&
1074 git ls-files -o >file_count &&
1075 test_line_count = 3 file_count &&
1077 test_seq 10 20 >merged-one &&
1078 test_seq 51 60 >merged-five &&
1079 # Determine what the merge of three would give us.
1080 test_seq 31 39 >three-base &&
1081 test_seq 31 40 >three-side-A &&
1082 test_seq 31 39 >three-side-B &&
1083 echo forty >>three-side-B &&
1084 test_must_fail git merge-file \
1088 three-side-A three-base three-side-B &&
1089 sed -e "s/^\([<=>]\)/\1\1/" three-side-A >merged-three &&
1091 # Verify the index is as expected
1092 git rev-parse >actual \
1096 git hash-object >expect \
1097 merged-one merged-three \
1098 merged-three merged-five \
1099 merged-five merged-one &&
1100 test_cmp expect actual &&
1102 git cat-file -p :2:two >expect &&
1103 git cat-file -p :3:two >other &&
1105 test_must_fail git merge-file \
1106 -L "HEAD" -L "" -L "B^0" \
1107 expect empty other &&
1108 test_cmp expect two &&
1110 git cat-file -p :2:four >expect &&
1111 git cat-file -p :3:four >other &&
1112 test_must_fail git merge-file \
1113 -L "HEAD" -L "" -L "B^0" \
1114 expect empty other &&
1115 test_cmp expect four &&
1117 git cat-file -p :2:six >expect &&
1118 git cat-file -p :3:six >other &&
1119 test_must_fail git merge-file \
1120 -L "HEAD" -L "" -L "B^0" \
1121 expect empty other &&
1126 test_conflicts_with_adds_and_renames() {
1138 # Both L and R have files named 'three' which collide. Each of
1139 # the colliding files could have been involved in a rename, in
1140 # which case there was a file named 'one' or 'two' that was
1141 # modified on the opposite side of history and renamed into the
1142 # collision on this side of history.
1145 # 1) The index should contain both a stage 2 and stage 3 entry
1146 # for the colliding file. Does it?
1147 # 2) When renames are involved, the content merges are clean, so
1148 # the index should reflect the content merges, not merely the
1149 # version of the colliding file from the prior commit. Does
1151 # 3) There should be a file in the worktree named 'three'
1152 # containing the two-way merged contents of the content-merged
1153 # versions of 'three' from each of the two colliding
1154 # files. Is it present?
1155 # 4) There should not be any three~* files in the working
1157 test_setup_collision_conflict () {
1158 #test_expect_success "setup simple $sideL/$sideR conflict" '
1159 test_create_repo simple_${sideL}_${sideR} &&
1161 cd simple_${sideL}_${sideR} &&
1163 # Create some related files now
1164 for i in $(test_seq 1 10)
1166 echo Random base content line $i
1168 cp file_v1 file_v2 &&
1169 echo modification >>file_v2 &&
1171 cp file_v1 file_v3 &&
1172 echo more stuff >>file_v3 &&
1173 cp file_v3 file_v4 &&
1174 echo yet more stuff >>file_v4 &&
1176 # Use a tag to record both these files for simple
1177 # access, and clean out these untracked files
1178 git tag file_v1 $(git hash-object -w file_v1) &&
1179 git tag file_v2 $(git hash-object -w file_v2) &&
1180 git tag file_v3 $(git hash-object -w file_v3) &&
1181 git tag file_v4 $(git hash-object -w file_v4) &&
1184 # Setup original commit (or merge-base), consisting of
1185 # files named "one" and "two" if renames were involved.
1186 touch irrelevant_file &&
1187 git add irrelevant_file &&
1188 if [ $sideL = "rename" ]
1190 git show file_v1 >one &&
1193 if [ $sideR = "rename" ]
1195 git show file_v3 >two &&
1198 test_tick && git commit -m initial &&
1203 # Handle the left side
1205 if [ $sideL = "rename" ]
1209 git show file_v2 >three &&
1212 if [ $sideR = "rename" ]
1214 git show file_v4 >two &&
1217 test_tick && git commit -m L &&
1219 # Handle the right side
1221 if [ $sideL = "rename" ]
1223 git show file_v2 >one &&
1226 if [ $sideR = "rename" ]
1230 git show file_v4 >three &&
1233 test_tick && git commit -m R
1238 test_expect_success "check simple $sideL/$sideR conflict" '
1239 test_setup_collision_conflict &&
1241 cd simple_${sideL}_${sideR} &&
1245 # Merge must fail; there is a conflict
1246 test_must_fail git merge -s recursive R^0 &&
1248 # Make sure the index has the right number of entries
1249 git ls-files -s >out &&
1250 test_line_count = 3 out &&
1251 git ls-files -u >out &&
1252 test_line_count = 2 out &&
1253 # Ensure we have the correct number of untracked files
1254 git ls-files -o >out &&
1255 test_line_count = 1 out &&
1257 # Nothing should have touched irrelevant_file
1258 git rev-parse >actual \
1259 :0:irrelevant_file \
1262 git rev-parse >expected \
1263 master:irrelevant_file \
1266 test_cmp expected actual &&
1268 # Make sure we have the correct merged contents for
1270 git show file_v1 >expected &&
1271 cat <<-\EOF >>expected &&
1280 test_cmp expected three
1285 test_conflicts_with_adds_and_renames rename rename
1286 test_conflicts_with_adds_and_renames rename add
1287 test_conflicts_with_adds_and_renames add rename
1288 test_conflicts_with_adds_and_renames add add
1298 # master has two files, named 'one' and 'two'.
1299 # branches L and R both modify 'one', in conflicting ways.
1300 # branches L and R both modify 'two', in conflicting ways.
1301 # branch L also renames 'one' to 'three'.
1302 # branch R also renames 'two' to 'three'.
1304 # So, we have four different conflicting files that all end up at path
1306 test_setup_nested_conflicts_from_rename_rename () {
1307 test_create_repo nested_conflicts_from_rename_rename &&
1309 cd nested_conflicts_from_rename_rename &&
1311 # Create some related files now
1312 for i in $(test_seq 1 10)
1314 echo Random base content line $i
1317 cp file_v1 file_v2 &&
1318 cp file_v1 file_v3 &&
1319 cp file_v1 file_v4 &&
1320 cp file_v1 file_v5 &&
1321 cp file_v1 file_v6 &&
1323 echo one >>file_v1 &&
1324 echo uno >>file_v2 &&
1325 echo eins >>file_v3 &&
1327 echo two >>file_v4 &&
1328 echo dos >>file_v5 &&
1329 echo zwei >>file_v6 &&
1331 # Setup original commit (or merge-base), consisting of
1332 # files named "one" and "two".
1336 test_tick && git commit -m english &&
1341 # Handle the left side
1344 mv -f file_v2 three &&
1345 mv -f file_v5 two &&
1346 git add two three &&
1347 test_tick && git commit -m spanish &&
1349 # Handle the right side
1352 mv -f file_v3 one &&
1353 mv -f file_v6 three &&
1354 git add one three &&
1355 test_tick && git commit -m german
1359 test_expect_success 'check nested conflicts from rename/rename(2to1)' '
1360 test_setup_nested_conflicts_from_rename_rename &&
1362 cd nested_conflicts_from_rename_rename &&
1366 # Merge must fail; there is a conflict
1367 test_must_fail git merge -s recursive R^0 &&
1369 # Make sure the index has the right number of entries
1370 git ls-files -s >out &&
1371 test_line_count = 2 out &&
1372 git ls-files -u >out &&
1373 test_line_count = 2 out &&
1374 # Ensure we have the correct number of untracked files
1375 git ls-files -o >out &&
1376 test_line_count = 1 out &&
1378 # Compare :2:three to expected values
1379 git cat-file -p master:one >base &&
1380 git cat-file -p L:three >ours &&
1381 git cat-file -p R:one >theirs &&
1382 test_must_fail git merge-file \
1383 -L "HEAD:three" -L "" -L "R^0:one" \
1385 sed -e "s/^\([<=>]\)/\1\1/" ours >L-three &&
1386 git cat-file -p :2:three >expect &&
1387 test_cmp expect L-three &&
1389 # Compare :2:three to expected values
1390 git cat-file -p master:two >base &&
1391 git cat-file -p L:two >ours &&
1392 git cat-file -p R:three >theirs &&
1393 test_must_fail git merge-file \
1394 -L "HEAD:two" -L "" -L "R^0:three" \
1396 sed -e "s/^\([<=>]\)/\1\1/" ours >R-three &&
1397 git cat-file -p :3:three >expect &&
1398 test_cmp expect R-three &&
1400 # Compare three to expected contents
1402 test_must_fail git merge-file \
1403 -L "HEAD" -L "" -L "R^0" \
1404 L-three empty R-three &&
1405 test_cmp three L-three
1409 # Testcase rename/rename(1to2) of a binary file
1413 # Expected: CONFLICT(rename/rename) message, three unstaged entries in the
1414 # index, and contents of orig-[AB] at path orig-[AB]
1415 test_setup_rename_rename_1_to_2_binary () {
1416 test_create_repo rename_rename_1_to_2_binary &&
1418 cd rename_rename_1_to_2_binary &&
1420 echo '* binary' >.gitattributes &&
1421 git add .gitattributes &&
1423 test_seq 1 10 >orig &&
1425 git commit -m orig &&
1431 git mv orig orig-A &&
1432 test_seq 1 11 >orig-A &&
1434 git commit -m orig-A &&
1437 git mv orig orig-B &&
1438 test_seq 0 10 >orig-B &&
1440 git commit -m orig-B
1445 test_expect_success 'rename/rename(1to2) with a binary file' '
1446 test_setup_rename_rename_1_to_2_binary &&
1448 cd rename_rename_1_to_2_binary &&
1452 test_must_fail git merge -s recursive B^0 &&
1454 # Make sure the index has the right number of entries
1455 git ls-files -s >actual &&
1456 test_line_count = 4 actual &&
1458 git rev-parse A:orig-A B:orig-B >expect &&
1459 git hash-object orig-A orig-B >actual &&
1460 test_cmp expect actual