| #!/bin/sh | 
 |  | 
 | test_description="recursive merge corner cases w/ renames but not criss-crosses" | 
 | # t6036 has corner cases that involve both criss-cross merges and renames | 
 |  | 
 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main | 
 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | 
 |  | 
 | . ./test-lib.sh | 
 |  | 
 | test_setup_rename_delete_untracked () { | 
 | 	git init rename-delete-untracked && | 
 | 	( | 
 | 		cd rename-delete-untracked && | 
 |  | 
 | 		echo "A pretty inscription" >ring && | 
 | 		git add ring && | 
 | 		test_tick && | 
 | 		git commit -m beginning && | 
 |  | 
 | 		git branch people && | 
 | 		git checkout -b rename-the-ring && | 
 | 		git mv ring one-ring-to-rule-them-all && | 
 | 		test_tick && | 
 | 		git commit -m fullname && | 
 |  | 
 | 		git checkout people && | 
 | 		git rm ring && | 
 | 		echo gollum >owner && | 
 | 		git add owner && | 
 | 		test_tick && | 
 | 		git commit -m track-people-instead-of-objects && | 
 | 		echo "Myyy PRECIOUSSS" >ring | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success "Does git preserve Gollum's precious artifact?" ' | 
 | 	test_setup_rename_delete_untracked && | 
 | 	( | 
 | 		cd rename-delete-untracked && | 
 |  | 
 | 		test_must_fail git merge -s recursive rename-the-ring && | 
 |  | 
 | 		# Make sure git did not delete an untracked file | 
 | 		test_path_is_file ring | 
 | 	) | 
 | ' | 
 |  | 
 | # Testcase setup for rename/modify/add-source: | 
 | #   Commit A: new file: a | 
 | #   Commit B: modify a slightly | 
 | #   Commit C: rename a->b, add completely different a | 
 | # | 
 | # We should be able to merge B & C cleanly | 
 |  | 
 | test_setup_rename_modify_add_source () { | 
 | 	git init rename-modify-add-source && | 
 | 	( | 
 | 		cd rename-modify-add-source && | 
 |  | 
 | 		printf "1\n2\n3\n4\n5\n6\n7\n" >a && | 
 | 		git add a && | 
 | 		git commit -m A && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b B A && | 
 | 		echo 8 >>a && | 
 | 		git add a && | 
 | 		git commit -m B && | 
 |  | 
 | 		git checkout -b C A && | 
 | 		git mv a b && | 
 | 		echo something completely different >a && | 
 | 		git add a && | 
 | 		git commit -m C | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_failure 'rename/modify/add-source conflict resolvable' ' | 
 | 	test_setup_rename_modify_add_source && | 
 | 	( | 
 | 		cd rename-modify-add-source && | 
 |  | 
 | 		git checkout B^0 && | 
 |  | 
 | 		git merge -s recursive C^0 && | 
 |  | 
 | 		git rev-parse >expect \ | 
 | 			B:a   C:a     && | 
 | 		git rev-parse >actual \ | 
 | 			b     c       && | 
 | 		test_cmp expect actual | 
 | 	) | 
 | ' | 
 |  | 
 | test_setup_break_detection_1 () { | 
 | 	git init break-detection-1 && | 
 | 	( | 
 | 		cd break-detection-1 && | 
 |  | 
 | 		printf "1\n2\n3\n4\n5\n" >a && | 
 | 		echo foo >b && | 
 | 		git add a b && | 
 | 		git commit -m A && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b B A && | 
 | 		git mv a c && | 
 | 		echo "Completely different content" >a && | 
 | 		git add a && | 
 | 		git commit -m B && | 
 |  | 
 | 		git checkout -b C A && | 
 | 		echo 6 >>a && | 
 | 		git add a && | 
 | 		git commit -m C | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_failure 'conflict caused if rename not detected' ' | 
 | 	test_setup_break_detection_1 && | 
 | 	( | 
 | 		cd break-detection-1 && | 
 |  | 
 | 		git checkout -q C^0 && | 
 | 		git merge -s recursive B^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 3 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 0 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		test_line_count = 6 c && | 
 | 		git rev-parse >expect \ | 
 | 			B:a   A:b     && | 
 | 		git rev-parse >actual \ | 
 | 			:0:a  :0:b    && | 
 | 		test_cmp expect actual | 
 | 	) | 
 | ' | 
 |  | 
 | test_setup_break_detection_2 () { | 
 | 	git init break-detection-2 && | 
 | 	( | 
 | 		cd break-detection-2 && | 
 |  | 
 | 		printf "1\n2\n3\n4\n5\n" >a && | 
 | 		echo foo >b && | 
 | 		git add a b && | 
 | 		git commit -m A && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b D A && | 
 | 		echo 7 >>a && | 
 | 		git add a && | 
 | 		git mv a c && | 
 | 		echo "Completely different content" >a && | 
 | 		git add a && | 
 | 		git commit -m D && | 
 |  | 
 | 		git checkout -b E A && | 
 | 		git rm a && | 
 | 		echo "Completely different content" >>a && | 
 | 		git add a && | 
 | 		git commit -m E | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_failure 'missed conflict if rename not detected' ' | 
 | 	test_setup_break_detection_2 && | 
 | 	( | 
 | 		cd break-detection-2 && | 
 |  | 
 | 		git checkout -q E^0 && | 
 | 		test_must_fail git merge -s recursive D^0 | 
 | 	) | 
 | ' | 
 |  | 
 | # Tests for undetected rename/add-source causing a file to erroneously be | 
 | # deleted (and for mishandled rename/rename(1to1) causing the same issue). | 
 | # | 
 | # This test uses a rename/rename(1to1)+add-source conflict (1to1 means the | 
 | # same file is renamed on both sides to the same thing; it should trigger | 
 | # the 1to2 logic, which it would do if the add-source didn't cause issues | 
 | # for git's rename detection): | 
 | #   Commit A: new file: a | 
 | #   Commit B: rename a->b | 
 | #   Commit C: rename a->b, add unrelated a | 
 |  | 
 | test_setup_break_detection_3 () { | 
 | 	git init break-detection-3 && | 
 | 	( | 
 | 		cd break-detection-3 && | 
 |  | 
 | 		printf "1\n2\n3\n4\n5\n" >a && | 
 | 		git add a && | 
 | 		git commit -m A && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b B A && | 
 | 		git mv a b && | 
 | 		git commit -m B && | 
 |  | 
 | 		git checkout -b C A && | 
 | 		git mv a b && | 
 | 		echo foobar >a && | 
 | 		git add a && | 
 | 		git commit -m C | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_failure 'detect rename/add-source and preserve all data' ' | 
 | 	test_setup_break_detection_3 && | 
 | 	( | 
 | 		cd break-detection-3 && | 
 |  | 
 | 		git checkout B^0 && | 
 |  | 
 | 		git merge -s recursive C^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		test_path_is_file a && | 
 | 		test_path_is_file b && | 
 |  | 
 | 		git rev-parse >expect \ | 
 | 			A:a   C:a     && | 
 | 		git rev-parse >actual \ | 
 | 			:0:b  :0:a    && | 
 | 		test_cmp expect actual | 
 | 	) | 
 | ' | 
 |  | 
 | test_expect_failure 'detect rename/add-source and preserve all data, merge other way' ' | 
 | 	test_setup_break_detection_3 && | 
 | 	( | 
 | 		cd break-detection-3 && | 
 |  | 
 | 		git checkout C^0 && | 
 |  | 
 | 		git merge -s recursive B^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		test_path_is_file a && | 
 | 		test_path_is_file b && | 
 |  | 
 | 		git rev-parse >expect \ | 
 | 			A:a   C:a     && | 
 | 		git rev-parse >actual \ | 
 | 			:0:b  :0:a    && | 
 | 		test_cmp expect actual | 
 | 	) | 
 | ' | 
 |  | 
 | test_setup_rename_directory () { | 
 | 	git init rename-directory-$1 && | 
 | 	( | 
 | 		cd rename-directory-$1 && | 
 |  | 
 | 		printf "1\n2\n3\n4\n5\n6\n" >file && | 
 | 		git add file && | 
 | 		test_tick && | 
 | 		git commit -m base && | 
 | 		git tag base && | 
 |  | 
 | 		git checkout -b right && | 
 | 		echo 7 >>file && | 
 | 		mkdir newfile && | 
 | 		echo junk >newfile/realfile && | 
 | 		git add file newfile/realfile && | 
 | 		test_tick && | 
 | 		git commit -m right && | 
 |  | 
 | 		git checkout -b left-conflict base && | 
 | 		echo 8 >>file && | 
 | 		git add file && | 
 | 		git mv file newfile && | 
 | 		test_tick && | 
 | 		git commit -m left && | 
 |  | 
 | 		git checkout -b left-clean base && | 
 | 		echo 0 >newfile && | 
 | 		cat file >>newfile && | 
 | 		git add newfile && | 
 | 		git rm file && | 
 | 		test_tick && | 
 | 		git commit -m left | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'rename/directory conflict + clean content merge' ' | 
 | 	test_setup_rename_directory 1a && | 
 | 	( | 
 | 		cd rename-directory-1a && | 
 |  | 
 | 		git checkout left-clean^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive right^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 1 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		echo 0 >expect && | 
 | 		git cat-file -p base:file >>expect && | 
 | 		echo 7 >>expect && | 
 | 		test_cmp expect newfile~HEAD && | 
 |  | 
 | 		test_path_is_file newfile/realfile && | 
 | 		test_path_is_file newfile~HEAD | 
 | 	) | 
 | ' | 
 |  | 
 | test_expect_success 'rename/directory conflict + content merge conflict' ' | 
 | 	test_setup_rename_directory 1b && | 
 | 	( | 
 | 		cd rename-directory-1b && | 
 |  | 
 | 		git reset --hard && | 
 | 		git clean -fdqx && | 
 |  | 
 | 		git checkout left-conflict^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive right^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 4 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 3 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		git cat-file -p left-conflict:newfile >left && | 
 | 		git cat-file -p base:file    >base && | 
 | 		git cat-file -p right:file   >right && | 
 | 		test_must_fail git merge-file \ | 
 | 			-L "HEAD:newfile" \ | 
 | 			-L "" \ | 
 | 			-L "right^0:file" \ | 
 | 			left base right && | 
 | 		test_cmp left newfile~HEAD && | 
 |  | 
 | 		git rev-parse >expect   \ | 
 | 			base:file       left-conflict:newfile right:file && | 
 | 		git rev-parse >actual \ | 
 | 			:1:newfile~HEAD :2:newfile~HEAD :3:newfile~HEAD && | 
 | 		test_cmp expect actual && | 
 |  | 
 | 		test_path_is_file newfile/realfile && | 
 | 		test_path_is_file newfile~HEAD | 
 | 	) | 
 | ' | 
 |  | 
 | test_setup_rename_directory_2 () { | 
 | 	git init rename-directory-2 && | 
 | 	( | 
 | 		cd rename-directory-2 && | 
 |  | 
 | 		mkdir sub && | 
 | 		printf "1\n2\n3\n4\n5\n6\n" >sub/file && | 
 | 		git add sub/file && | 
 | 		test_tick && | 
 | 		git commit -m base && | 
 | 		git tag base && | 
 |  | 
 | 		git checkout -b right && | 
 | 		echo 7 >>sub/file && | 
 | 		git add sub/file && | 
 | 		test_tick && | 
 | 		git commit -m right && | 
 |  | 
 | 		git checkout -b left base && | 
 | 		echo 0 >newfile && | 
 | 		cat sub/file >>newfile && | 
 | 		git rm sub/file && | 
 | 		mv newfile sub && | 
 | 		git add sub && | 
 | 		test_tick && | 
 | 		git commit -m left | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'disappearing dir in rename/directory conflict handled' ' | 
 | 	test_setup_rename_directory_2 && | 
 | 	( | 
 | 		cd rename-directory-2 && | 
 |  | 
 | 		git checkout left^0 && | 
 |  | 
 | 		git merge -s recursive right^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 1 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 0 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		echo 0 >expect && | 
 | 		git cat-file -p base:sub/file >>expect && | 
 | 		echo 7 >>expect && | 
 | 		test_cmp expect sub && | 
 |  | 
 | 		test_path_is_file sub | 
 | 	) | 
 | ' | 
 |  | 
 | # Test for basic rename/add-dest conflict, with rename needing content merge: | 
 | #   Commit O: a | 
 | #   Commit A: rename a->b, modifying b too | 
 | #   Commit B: modify a, add different b | 
 |  | 
 | test_setup_rename_with_content_merge_and_add () { | 
 | 	git init rename-with-content-merge-and-add-$1 && | 
 | 	( | 
 | 		cd rename-with-content-merge-and-add-$1 && | 
 |  | 
 | 		test_seq 1 5 >a && | 
 | 		git add a && | 
 | 		git commit -m O && | 
 | 		git tag O && | 
 |  | 
 | 		git checkout -b A O && | 
 | 		git mv a b && | 
 | 		test_seq 0 5 >b && | 
 | 		git add b && | 
 | 		git commit -m A && | 
 |  | 
 | 		git checkout -b B O && | 
 | 		echo 6 >>a && | 
 | 		echo hello world >b && | 
 | 		git add a b && | 
 | 		git commit -m B | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'handle rename-with-content-merge vs. add' ' | 
 | 	test_setup_rename_with_content_merge_and_add AB && | 
 | 	( | 
 | 		cd rename-with-content-merge-and-add-AB && | 
 |  | 
 | 		git checkout A^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive B^0 >out && | 
 | 		test_grep "CONFLICT (.*/add)" out && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 2 out && | 
 | 		# Also, make sure both unmerged entries are for "b" | 
 | 		git ls-files -u b >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		test_path_is_missing a && | 
 | 		test_path_is_file b && | 
 |  | 
 | 		test_seq 0 6 >tmp && | 
 | 		git hash-object tmp >expect && | 
 | 		git rev-parse B:b >>expect && | 
 | 		git rev-parse >actual  \ | 
 | 			:2:b    :3:b   && | 
 | 		test_cmp expect actual && | 
 |  | 
 | 		# Test that the two-way merge in b is as expected | 
 | 		git cat-file -p :2:b >>ours && | 
 | 		git cat-file -p :3:b >>theirs && | 
 | 		>empty && | 
 | 		test_must_fail git merge-file \ | 
 | 			-L "HEAD" \ | 
 | 			-L "" \ | 
 | 			-L "B^0" \ | 
 | 			ours empty theirs && | 
 | 		test_cmp ours b | 
 | 	) | 
 | ' | 
 |  | 
 | test_expect_success 'handle rename-with-content-merge vs. add, merge other way' ' | 
 | 	test_setup_rename_with_content_merge_and_add BA && | 
 | 	( | 
 | 		cd rename-with-content-merge-and-add-BA && | 
 |  | 
 | 		git reset --hard && | 
 | 		git clean -fdx && | 
 |  | 
 | 		git checkout B^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive A^0 >out && | 
 | 		test_grep "CONFLICT (.*/add)" out && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 2 out && | 
 | 		# Also, make sure both unmerged entries are for "b" | 
 | 		git ls-files -u b >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		test_path_is_missing a && | 
 | 		test_path_is_file b && | 
 |  | 
 | 		test_seq 0 6 >tmp && | 
 | 		git rev-parse B:b >expect && | 
 | 		git hash-object tmp >>expect && | 
 | 		git rev-parse >actual  \ | 
 | 			:2:b    :3:b   && | 
 | 		test_cmp expect actual && | 
 |  | 
 | 		# Test that the two-way merge in b is as expected | 
 | 		git cat-file -p :2:b >>ours && | 
 | 		git cat-file -p :3:b >>theirs && | 
 | 		>empty && | 
 | 		test_must_fail git merge-file \ | 
 | 			-L "HEAD" \ | 
 | 			-L "" \ | 
 | 			-L "A^0" \ | 
 | 			ours empty theirs && | 
 | 		test_cmp ours b | 
 | 	) | 
 | ' | 
 |  | 
 | # Test for all kinds of things that can go wrong with rename/rename (2to1): | 
 | #   Commit A: new files: a & b | 
 | #   Commit B: rename a->c, modify b | 
 | #   Commit C: rename b->c, modify a | 
 | # | 
 | # Merging of B & C should NOT be clean.  Questions: | 
 | #   * Both a & b should be removed by the merge; are they? | 
 | #   * The two c's should contain modifications to a & b; do they? | 
 | #   * The index should contain two files, both for c; does it? | 
 | #   * The working copy should have two files, both of form c~<unique>; does it? | 
 | #   * Nothing else should be present.  Is anything? | 
 |  | 
 | test_setup_rename_rename_2to1 () { | 
 | 	git init rename-rename-2to1 && | 
 | 	( | 
 | 		cd rename-rename-2to1 && | 
 |  | 
 | 		printf "1\n2\n3\n4\n5\n" >a && | 
 | 		printf "5\n4\n3\n2\n1\n" >b && | 
 | 		git add a b && | 
 | 		git commit -m A && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b B A && | 
 | 		git mv a c && | 
 | 		echo 0 >>b && | 
 | 		git add b && | 
 | 		git commit -m B && | 
 |  | 
 | 		git checkout -b C A && | 
 | 		git mv b c && | 
 | 		echo 6 >>a && | 
 | 		git add a && | 
 | 		git commit -m C | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'handle rename/rename (2to1) conflict correctly' ' | 
 | 	test_setup_rename_rename_2to1 && | 
 | 	( | 
 | 		cd rename-rename-2to1 && | 
 |  | 
 | 		git checkout B^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive C^0 >out && | 
 | 		test_grep "CONFLICT (\(.*\)/\1)" out && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u c >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		test_path_is_missing a && | 
 | 		test_path_is_missing b && | 
 |  | 
 | 		git rev-parse >expect  \ | 
 | 			C:a     B:b    && | 
 | 		git rev-parse >actual  \ | 
 | 			:2:c    :3:c   && | 
 | 		test_cmp expect actual && | 
 |  | 
 | 		# Test that the two-way merge in new_a is as expected | 
 | 		git cat-file -p :2:c >>ours && | 
 | 		git cat-file -p :3:c >>theirs && | 
 | 		>empty && | 
 | 		test_must_fail git merge-file \ | 
 | 			-L "HEAD" \ | 
 | 			-L "" \ | 
 | 			-L "C^0" \ | 
 | 			ours empty theirs && | 
 | 		git hash-object c >actual && | 
 | 		git hash-object ours >expect && | 
 | 		test_cmp expect actual | 
 | 	) | 
 | ' | 
 |  | 
 | # Testcase setup for simple rename/rename (1to2) conflict: | 
 | #   Commit A: new file: a | 
 | #   Commit B: rename a->b | 
 | #   Commit C: rename a->c | 
 | test_setup_rename_rename_1to2 () { | 
 | 	git init rename-rename-1to2 && | 
 | 	( | 
 | 		cd rename-rename-1to2 && | 
 |  | 
 | 		echo stuff >a && | 
 | 		git add a && | 
 | 		test_tick && | 
 | 		git commit -m A && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b B A && | 
 | 		git mv a b && | 
 | 		test_tick && | 
 | 		git commit -m B && | 
 |  | 
 | 		git checkout -b C A && | 
 | 		git mv a c && | 
 | 		test_tick && | 
 | 		git commit -m C | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'merge has correct working tree contents' ' | 
 | 	test_setup_rename_rename_1to2 && | 
 | 	( | 
 | 		cd rename-rename-1to2 && | 
 |  | 
 | 		git checkout C^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive B^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 3 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 3 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		test_path_is_missing a && | 
 | 		git rev-parse >expect   \ | 
 | 			A:a   A:a   A:a \ | 
 | 			A:a   A:a       && | 
 | 		git rev-parse >actual    \ | 
 | 			:1:a  :3:b  :2:c && | 
 | 		git hash-object >>actual \ | 
 | 			b     c          && | 
 | 		test_cmp expect actual | 
 | 	) | 
 | ' | 
 |  | 
 | # Testcase setup for rename/rename(1to2)/add-source conflict: | 
 | #   Commit A: new file: a | 
 | #   Commit B: rename a->b | 
 | #   Commit C: rename a->c, add completely different a | 
 | # | 
 | # Merging of B & C should NOT be clean; there's a rename/rename conflict | 
 |  | 
 | test_setup_rename_rename_1to2_add_source_1 () { | 
 | 	git init rename-rename-1to2-add-source-1 && | 
 | 	( | 
 | 		cd rename-rename-1to2-add-source-1 && | 
 |  | 
 | 		printf "1\n2\n3\n4\n5\n6\n7\n" >a && | 
 | 		git add a && | 
 | 		git commit -m A && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b B A && | 
 | 		git mv a b && | 
 | 		git commit -m B && | 
 |  | 
 | 		git checkout -b C A && | 
 | 		git mv a c && | 
 | 		echo something completely different >a && | 
 | 		git add a && | 
 | 		git commit -m C | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge' ' | 
 | 	test_setup_rename_rename_1to2_add_source_1 && | 
 | 	( | 
 | 		cd rename-rename-1to2-add-source-1 && | 
 |  | 
 | 		git checkout B^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive C^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 4 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		git rev-parse >expect         \ | 
 | 			C:a   A:a   B:b   C:C && | 
 | 		git rev-parse >actual          \ | 
 | 			:3:a  :1:a  :2:b  :3:c && | 
 | 		test_cmp expect actual && | 
 |  | 
 | 		test_path_is_file a && | 
 | 		test_path_is_file b && | 
 | 		test_path_is_file c | 
 | 	) | 
 | ' | 
 |  | 
 | test_setup_rename_rename_1to2_add_source_2 () { | 
 | 	git init rename-rename-1to2-add-source-2 && | 
 | 	( | 
 | 		cd rename-rename-1to2-add-source-2 && | 
 |  | 
 | 		>a && | 
 | 		git add a && | 
 | 		test_tick && | 
 | 		git commit -m base && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b B A && | 
 | 		git mv a b && | 
 | 		test_tick && | 
 | 		git commit -m one && | 
 |  | 
 | 		git checkout -b C A && | 
 | 		git mv a b && | 
 | 		echo important-info >a && | 
 | 		git add a && | 
 | 		test_tick && | 
 | 		git commit -m two | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_failure 'rename/rename/add-source still tracks new a file' ' | 
 | 	test_setup_rename_rename_1to2_add_source_2 && | 
 | 	( | 
 | 		cd rename-rename-1to2-add-source-2 && | 
 |  | 
 | 		git checkout C^0 && | 
 | 		git merge -s recursive B^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		git rev-parse >expect \ | 
 | 			C:a   A:a     && | 
 | 		git rev-parse >actual \ | 
 | 			:0:a  :0:b    && | 
 | 		test_cmp expect actual | 
 | 	) | 
 | ' | 
 |  | 
 | test_setup_rename_rename_1to2_add_dest () { | 
 | 	git init rename-rename-1to2-add-dest && | 
 | 	( | 
 | 		cd rename-rename-1to2-add-dest && | 
 |  | 
 | 		echo stuff >a && | 
 | 		git add a && | 
 | 		test_tick && | 
 | 		git commit -m base && | 
 | 		git tag A && | 
 |  | 
 | 		git checkout -b B A && | 
 | 		git mv a b && | 
 | 		echo precious-data >c && | 
 | 		git add c && | 
 | 		test_tick && | 
 | 		git commit -m one && | 
 |  | 
 | 		git checkout -b C A && | 
 | 		git mv a c && | 
 | 		echo important-info >b && | 
 | 		git add b && | 
 | 		test_tick && | 
 | 		git commit -m two | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'rename/rename/add-dest merge still knows about conflicting file versions' ' | 
 | 	test_setup_rename_rename_1to2_add_dest && | 
 | 	( | 
 | 		cd rename-rename-1to2-add-dest && | 
 |  | 
 | 		git checkout C^0 && | 
 | 		test_must_fail git merge -s recursive B^0 && | 
 |  | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 5 out && | 
 | 		git ls-files -u b >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u c >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		git rev-parse >expect               \ | 
 | 			A:a   C:b   B:b   C:c   B:c && | 
 | 		git rev-parse >actual                \ | 
 | 			:1:a  :2:b  :3:b  :2:c  :3:c && | 
 | 		test_cmp expect actual && | 
 |  | 
 | 		# Record some contents for re-doing merges | 
 | 		git cat-file -p A:a >stuff && | 
 | 		git cat-file -p C:b >important_info && | 
 | 		git cat-file -p B:c >precious_data && | 
 | 		>empty && | 
 |  | 
 | 		# Test the merge in b | 
 | 		test_must_fail git merge-file \ | 
 | 			-L "HEAD" \ | 
 | 			-L "" \ | 
 | 			-L "B^0" \ | 
 | 			important_info empty stuff && | 
 | 		test_cmp important_info b && | 
 |  | 
 | 		# Test the merge in c | 
 | 		test_must_fail git merge-file \ | 
 | 			-L "HEAD" \ | 
 | 			-L "" \ | 
 | 			-L "B^0" \ | 
 | 			stuff empty precious_data && | 
 | 		test_cmp stuff c | 
 | 	) | 
 | ' | 
 |  | 
 | # Testcase rad, rename/add/delete | 
 | #   Commit O: foo | 
 | #   Commit A: rm foo, add different bar | 
 | #   Commit B: rename foo->bar | 
 | #   Expected: CONFLICT (rename/add/delete), two-way merged bar | 
 |  | 
 | test_setup_rad () { | 
 | 	git init rad && | 
 | 	( | 
 | 		cd rad && | 
 | 		echo "original file" >foo && | 
 | 		git add foo && | 
 | 		git commit -m "original" && | 
 |  | 
 | 		git branch O && | 
 | 		git branch A && | 
 | 		git branch B && | 
 |  | 
 | 		git checkout A && | 
 | 		git rm foo && | 
 | 		echo "different file" >bar && | 
 | 		git add bar && | 
 | 		git commit -m "Remove foo, add bar" && | 
 |  | 
 | 		git checkout B && | 
 | 		git mv foo bar && | 
 | 		git commit -m "rename foo to bar" | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'rad-check: rename/add/delete conflict' ' | 
 | 	test_setup_rad && | 
 | 	( | 
 | 		cd rad && | 
 |  | 
 | 		git checkout B^0 && | 
 | 		test_must_fail git merge -s recursive A^0 >out 2>err && | 
 |  | 
 | 		# Instead of requiring the output to contain one combined line | 
 | 		#   CONFLICT (rename/add/delete) | 
 | 		# or perhaps two lines: | 
 | 		#   CONFLICT (rename/add): new file collides with rename target | 
 | 		#   CONFLICT (rename/delete): rename source removed on other side | 
 | 		# and instead of requiring "rename/add" instead of "add/add", | 
 | 		# be flexible in the type of console output message(s) reported | 
 | 		# for this particular case; we will be more stringent about the | 
 | 		# contents of the index and working directory. | 
 | 		test_grep "CONFLICT (.*/add)" out && | 
 | 		test_grep "CONFLICT (rename.*/delete)" out && | 
 | 		test_must_be_empty err && | 
 |  | 
 | 		git ls-files -s >file_count && | 
 | 		test_line_count = 2 file_count && | 
 | 		git ls-files -u >file_count && | 
 | 		test_line_count = 2 file_count && | 
 | 		git ls-files -o >file_count && | 
 | 		test_line_count = 3 file_count && | 
 |  | 
 | 		git rev-parse >actual \ | 
 | 			:2:bar :3:bar && | 
 | 		git rev-parse >expect \ | 
 | 			B:bar  A:bar  && | 
 |  | 
 | 		test_path_is_missing foo && | 
 | 		# bar should have two-way merged contents of the different | 
 | 		# versions of bar; check that content from both sides is | 
 | 		# present. | 
 | 		grep original bar && | 
 | 		grep different bar | 
 | 	) | 
 | ' | 
 |  | 
 | # Testcase rrdd, rename/rename(2to1)/delete/delete | 
 | #   Commit O: foo, bar | 
 | #   Commit A: rename foo->baz, rm bar | 
 | #   Commit B: rename bar->baz, rm foo | 
 | #   Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz | 
 |  | 
 | test_setup_rrdd () { | 
 | 	git init rrdd && | 
 | 	( | 
 | 		cd rrdd && | 
 | 		echo foo >foo && | 
 | 		echo bar >bar && | 
 | 		git add foo bar && | 
 | 		git commit -m O && | 
 |  | 
 | 		git branch O && | 
 | 		git branch A && | 
 | 		git branch B && | 
 |  | 
 | 		git checkout A && | 
 | 		git mv foo baz && | 
 | 		git rm bar && | 
 | 		git commit -m "Rename foo, remove bar" && | 
 |  | 
 | 		git checkout B && | 
 | 		git mv bar baz && | 
 | 		git rm foo && | 
 | 		git commit -m "Rename bar, remove foo" | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'rrdd-check: rename/rename(2to1)/delete/delete conflict' ' | 
 | 	test_setup_rrdd && | 
 | 	( | 
 | 		cd rrdd && | 
 |  | 
 | 		git checkout A^0 && | 
 | 		test_must_fail git merge -s recursive B^0 >out 2>err && | 
 |  | 
 | 		# Instead of requiring the output to contain one combined line | 
 | 		#   CONFLICT (rename/rename/delete/delete) | 
 | 		# or perhaps two lines: | 
 | 		#   CONFLICT (rename/rename): ... | 
 | 		#   CONFLICT (rename/delete): info about pair 1 | 
 | 		#   CONFLICT (rename/delete): info about pair 2 | 
 | 		# and instead of requiring "rename/rename" instead of "add/add", | 
 | 		# be flexible in the type of console output message(s) reported | 
 | 		# for this particular case; we will be more stringent about the | 
 | 		# contents of the index and working directory. | 
 | 		test_grep "CONFLICT (\(.*\)/\1)" out && | 
 | 		test_grep "CONFLICT (rename.*delete)" out && | 
 | 		test_must_be_empty err && | 
 |  | 
 | 		git ls-files -s >file_count && | 
 | 		test_line_count = 2 file_count && | 
 | 		git ls-files -u >file_count && | 
 | 		test_line_count = 2 file_count && | 
 | 		git ls-files -o >file_count && | 
 | 		test_line_count = 3 file_count && | 
 |  | 
 | 		git rev-parse >actual \ | 
 | 			:2:baz :3:baz && | 
 | 		git rev-parse >expect \ | 
 | 			O:foo  O:bar  && | 
 |  | 
 | 		test_path_is_missing foo && | 
 | 		test_path_is_missing bar && | 
 | 		# baz should have two-way merged contents of the original | 
 | 		# contents of foo and bar; check that content from both sides | 
 | 		# is present. | 
 | 		grep foo baz && | 
 | 		grep bar baz | 
 | 	) | 
 | ' | 
 |  | 
 | # Testcase mod6, chains of rename/rename(1to2) and rename/rename(2to1) | 
 | #   Commit O: one,      three,       five | 
 | #   Commit A: one->two, three->four, five->six | 
 | #   Commit B: one->six, three->two,  five->four | 
 | #   Expected: six CONFLICT(rename/rename) messages, each path in two of the | 
 | #             multi-way merged contents found in two, four, six | 
 |  | 
 | test_setup_mod6 () { | 
 | 	git init mod6 && | 
 | 	( | 
 | 		cd mod6 && | 
 | 		test_seq 11 19 >one && | 
 | 		test_seq 31 39 >three && | 
 | 		test_seq 51 59 >five && | 
 | 		git add . && | 
 | 		test_tick && | 
 | 		git commit -m "O" && | 
 |  | 
 | 		git branch O && | 
 | 		git branch A && | 
 | 		git branch B && | 
 |  | 
 | 		git checkout A && | 
 | 		test_seq 10 19 >one && | 
 | 		echo 40        >>three && | 
 | 		git add one three && | 
 | 		git mv  one   two  && | 
 | 		git mv  three four && | 
 | 		git mv  five  six  && | 
 | 		test_tick && | 
 | 		git commit -m "A" && | 
 |  | 
 | 		git checkout B && | 
 | 		echo 20    >>one       && | 
 | 		echo forty >>three     && | 
 | 		echo 60    >>five      && | 
 | 		git add one three five && | 
 | 		git mv  one   six  && | 
 | 		git mv  three two  && | 
 | 		git mv  five  four && | 
 | 		test_tick && | 
 | 		git commit -m "B" | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' ' | 
 | 	test_setup_mod6 && | 
 | 	( | 
 | 		cd mod6 && | 
 |  | 
 | 		git checkout A^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive B^0 >out 2>err && | 
 |  | 
 | 		test_grep "CONFLICT (rename/rename)" out && | 
 | 		test_must_be_empty err && | 
 |  | 
 | 		git ls-files -s >file_count && | 
 | 		test_line_count = 9 file_count && | 
 | 		git ls-files -u >file_count && | 
 | 		test_line_count = 9 file_count && | 
 | 		git ls-files -o >file_count && | 
 | 		test_line_count = 3 file_count && | 
 |  | 
 | 		test_seq 10 20 >merged-one && | 
 | 		test_seq 51 60 >merged-five && | 
 | 		# Determine what the merge of three would give us. | 
 | 		test_seq 31 39 >three-base && | 
 | 		test_seq 31 40 >three-side-A && | 
 | 		test_seq 31 39 >three-side-B && | 
 | 		echo forty >>three-side-B && | 
 | 		test_must_fail git merge-file \ | 
 | 			-L "HEAD:four" \ | 
 | 			-L "" \ | 
 | 			-L "B^0:two" \ | 
 | 			three-side-A three-base three-side-B && | 
 | 		sed -e "s/^\([<=>]\)/\1\1/" three-side-A >merged-three && | 
 |  | 
 | 		# Verify the index is as expected | 
 | 		git rev-parse >actual         \ | 
 | 			:2:two       :3:two   \ | 
 | 			:2:four      :3:four  \ | 
 | 			:2:six       :3:six   && | 
 | 		git hash-object >expect           \ | 
 | 			merged-one   merged-three \ | 
 | 			merged-three merged-five  \ | 
 | 			merged-five  merged-one   && | 
 | 		test_cmp expect actual && | 
 |  | 
 | 		git cat-file -p :2:two >expect && | 
 | 		git cat-file -p :3:two >other && | 
 | 		>empty && | 
 | 		test_must_fail git merge-file    \ | 
 | 			-L "HEAD"  -L ""  -L "B^0" \ | 
 | 			expect     empty  other && | 
 | 		test_cmp expect two && | 
 |  | 
 | 		git cat-file -p :2:four >expect && | 
 | 		git cat-file -p :3:four >other && | 
 | 		test_must_fail git merge-file    \ | 
 | 			-L "HEAD"  -L ""  -L "B^0" \ | 
 | 			expect     empty  other && | 
 | 		test_cmp expect four && | 
 |  | 
 | 		git cat-file -p :2:six >expect && | 
 | 		git cat-file -p :3:six >other && | 
 | 		test_must_fail git merge-file    \ | 
 | 			-L "HEAD"  -L ""  -L "B^0" \ | 
 | 			expect     empty  other && | 
 | 		test_cmp expect six | 
 | 	) | 
 | ' | 
 |  | 
 | test_conflicts_with_adds_and_renames() { | 
 | 	sideL=$1 | 
 | 	sideR=$2 | 
 |  | 
 | 	# Setup: | 
 | 	#          L | 
 | 	#         / \ | 
 | 	#     main   ? | 
 | 	#         \ / | 
 | 	#          R | 
 | 	# | 
 | 	# Where: | 
 | 	#   Both L and R have files named 'three' which collide.  Each of | 
 | 	#   the colliding files could have been involved in a rename, in | 
 | 	#   which case there was a file named 'one' or 'two' that was | 
 | 	#   modified on the opposite side of history and renamed into the | 
 | 	#   collision on this side of history. | 
 | 	# | 
 | 	# Questions: | 
 | 	#   1) The index should contain both a stage 2 and stage 3 entry | 
 | 	#      for the colliding file.  Does it? | 
 | 	#   2) When renames are involved, the content merges are clean, so | 
 | 	#      the index should reflect the content merges, not merely the | 
 | 	#      version of the colliding file from the prior commit.  Does | 
 | 	#      it? | 
 | 	#   3) There should be a file in the worktree named 'three' | 
 | 	#      containing the two-way merged contents of the content-merged | 
 | 	#      versions of 'three' from each of the two colliding | 
 | 	#      files.  Is it present? | 
 | 	#   4) There should not be any three~* files in the working | 
 | 	#      tree | 
 | 	test_setup_collision_conflict () { | 
 | 		git init simple_${sideL}_${sideR} && | 
 | 		( | 
 | 			cd simple_${sideL}_${sideR} && | 
 |  | 
 | 			# Create some related files now | 
 | 			test_seq -f "Random base content line %d" 1 10 >file_v1 && | 
 | 			cp file_v1 file_v2 && | 
 | 			echo modification >>file_v2 && | 
 |  | 
 | 			cp file_v1 file_v3 && | 
 | 			echo more stuff >>file_v3 && | 
 | 			cp file_v3 file_v4 && | 
 | 			echo yet more stuff >>file_v4 && | 
 |  | 
 | 			# Use a tag to record both these files for simple | 
 | 			# access, and clean out these untracked files | 
 | 			git tag file_v1 $(git hash-object -w file_v1) && | 
 | 			git tag file_v2 $(git hash-object -w file_v2) && | 
 | 			git tag file_v3 $(git hash-object -w file_v3) && | 
 | 			git tag file_v4 $(git hash-object -w file_v4) && | 
 | 			git clean -f && | 
 |  | 
 | 			# Setup original commit (or merge-base), consisting of | 
 | 			# files named "one" and "two" if renames were involved. | 
 | 			touch irrelevant_file && | 
 | 			git add irrelevant_file && | 
 | 			if [ $sideL = "rename" ] | 
 | 			then | 
 | 				git show file_v1 >one && | 
 | 				git add one | 
 | 			fi && | 
 | 			if [ $sideR = "rename" ] | 
 | 			then | 
 | 				git show file_v3 >two && | 
 | 				git add two | 
 | 			fi && | 
 | 			test_tick && git commit -m initial && | 
 |  | 
 | 			git branch L && | 
 | 			git branch R && | 
 |  | 
 | 			# Handle the left side | 
 | 			git checkout L && | 
 | 			if [ $sideL = "rename" ] | 
 | 			then | 
 | 				git mv one three | 
 | 			else | 
 | 				git show file_v2 >three && | 
 | 				git add three | 
 | 			fi && | 
 | 			if [ $sideR = "rename" ] | 
 | 			then | 
 | 				git show file_v4 >two && | 
 | 				git add two | 
 | 			fi && | 
 | 			test_tick && git commit -m L && | 
 |  | 
 | 			# Handle the right side | 
 | 			git checkout R && | 
 | 			if [ $sideL = "rename" ] | 
 | 			then | 
 | 				git show file_v2 >one && | 
 | 				git add one | 
 | 			fi && | 
 | 			if [ $sideR = "rename" ] | 
 | 			then | 
 | 				git mv two three | 
 | 			else | 
 | 				git show file_v4 >three && | 
 | 				git add three | 
 | 			fi && | 
 | 			test_tick && git commit -m R | 
 | 		) | 
 | 	} | 
 |  | 
 | 	test_expect_success "check simple $sideL/$sideR conflict" ' | 
 | 		test_setup_collision_conflict && | 
 | 		( | 
 | 			cd simple_${sideL}_${sideR} && | 
 |  | 
 | 			git checkout L^0 && | 
 |  | 
 | 			# Merge must fail; there is a conflict | 
 | 			test_must_fail git merge -s recursive R^0 && | 
 |  | 
 | 			# Make sure the index has the right number of entries | 
 | 			git ls-files -s >out && | 
 | 			test_line_count = 3 out && | 
 | 			git ls-files -u >out && | 
 | 			test_line_count = 2 out && | 
 | 			# Ensure we have the correct number of untracked files | 
 | 			git ls-files -o >out && | 
 | 			test_line_count = 1 out && | 
 |  | 
 | 			# Nothing should have touched irrelevant_file | 
 | 			git rev-parse >actual      \ | 
 | 				:0:irrelevant_file \ | 
 | 				:2:three           \ | 
 | 				:3:three           && | 
 | 			git rev-parse >expected        \ | 
 | 				main:irrelevant_file \ | 
 | 				file_v2                \ | 
 | 				file_v4                && | 
 | 			test_cmp expected actual && | 
 |  | 
 | 			# Make sure we have the correct merged contents for | 
 | 			# three | 
 | 			git show file_v1 >expected && | 
 | 			cat <<-\EOF >>expected && | 
 | 			<<<<<<< HEAD | 
 | 			modification | 
 | 			======= | 
 | 			more stuff | 
 | 			yet more stuff | 
 | 			>>>>>>> R^0 | 
 | 			EOF | 
 |  | 
 | 			test_cmp expected three | 
 | 		) | 
 | 	' | 
 | } | 
 |  | 
 | test_conflicts_with_adds_and_renames rename rename | 
 | test_conflicts_with_adds_and_renames rename add | 
 | test_conflicts_with_adds_and_renames add    rename | 
 | test_conflicts_with_adds_and_renames add    add | 
 |  | 
 | # Setup: | 
 | #          L | 
 | #         / \ | 
 | #     main   ? | 
 | #         \ / | 
 | #          R | 
 | # | 
 | # Where: | 
 | #   main has two files, named 'one' and 'two'. | 
 | #   branches L and R both modify 'one', in conflicting ways. | 
 | #   branches L and R both modify 'two', in conflicting ways. | 
 | #   branch L also renames 'one' to 'three'. | 
 | #   branch R also renames 'two' to 'three'. | 
 | # | 
 | #   So, we have four different conflicting files that all end up at path | 
 | #   'three'. | 
 | test_setup_nested_conflicts_from_rename_rename () { | 
 | 	git init nested_conflicts_from_rename_rename && | 
 | 	( | 
 | 		cd nested_conflicts_from_rename_rename && | 
 |  | 
 | 		# Create some related files now | 
 | 		test_seq -f "Random base content line %d" 1 10 >file_v1 && | 
 |  | 
 | 		cp file_v1 file_v2 && | 
 | 		cp file_v1 file_v3 && | 
 | 		cp file_v1 file_v4 && | 
 | 		cp file_v1 file_v5 && | 
 | 		cp file_v1 file_v6 && | 
 |  | 
 | 		echo one  >>file_v1 && | 
 | 		echo uno  >>file_v2 && | 
 | 		echo eins >>file_v3 && | 
 |  | 
 | 		echo two  >>file_v4 && | 
 | 		echo dos  >>file_v5 && | 
 | 		echo zwei >>file_v6 && | 
 |  | 
 | 		# Setup original commit (or merge-base), consisting of | 
 | 		# files named "one" and "two". | 
 | 		mv file_v1 one && | 
 | 		mv file_v4 two && | 
 | 		git add one two && | 
 | 		test_tick && git commit -m english && | 
 |  | 
 | 		git branch L && | 
 | 		git branch R && | 
 |  | 
 | 		# Handle the left side | 
 | 		git checkout L && | 
 | 		git rm one two && | 
 | 		mv -f file_v2 three && | 
 | 		mv -f file_v5 two && | 
 | 		git add two three && | 
 | 		test_tick && git commit -m spanish && | 
 |  | 
 | 		# Handle the right side | 
 | 		git checkout R && | 
 | 		git rm one two && | 
 | 		mv -f file_v3 one && | 
 | 		mv -f file_v6 three && | 
 | 		git add one three && | 
 | 		test_tick && git commit -m german | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'check nested conflicts from rename/rename(2to1)' ' | 
 | 	test_setup_nested_conflicts_from_rename_rename && | 
 | 	( | 
 | 		cd nested_conflicts_from_rename_rename && | 
 |  | 
 | 		git checkout L^0 && | 
 |  | 
 | 		# Merge must fail; there is a conflict | 
 | 		test_must_fail git merge -s recursive R^0 && | 
 |  | 
 | 		# Make sure the index has the right number of entries | 
 | 		git ls-files -s >out && | 
 | 		test_line_count = 2 out && | 
 | 		git ls-files -u >out && | 
 | 		test_line_count = 2 out && | 
 | 		# Ensure we have the correct number of untracked files | 
 | 		git ls-files -o >out && | 
 | 		test_line_count = 1 out && | 
 |  | 
 | 		# Compare :2:three to expected values | 
 | 		git cat-file -p main:one >base && | 
 | 		git cat-file -p L:three >ours && | 
 | 		git cat-file -p R:one >theirs && | 
 | 		test_must_fail git merge-file    \ | 
 | 			-L "HEAD:three"  -L ""  -L "R^0:one" \ | 
 | 			ours             base   theirs && | 
 | 		sed -e "s/^\([<=>]\)/\1\1/" ours >L-three && | 
 | 		git cat-file -p :2:three >expect && | 
 | 		test_cmp expect L-three && | 
 |  | 
 | 		# Compare :2:three to expected values | 
 | 		git cat-file -p main:two >base && | 
 | 		git cat-file -p L:two >ours && | 
 | 		git cat-file -p R:three >theirs && | 
 | 		test_must_fail git merge-file    \ | 
 | 			-L "HEAD:two"  -L ""  -L "R^0:three" \ | 
 | 			ours           base   theirs && | 
 | 		sed -e "s/^\([<=>]\)/\1\1/" ours >R-three && | 
 | 		git cat-file -p :3:three >expect && | 
 | 		test_cmp expect R-three && | 
 |  | 
 | 		# Compare three to expected contents | 
 | 		>empty && | 
 | 		test_must_fail git merge-file    \ | 
 | 			-L "HEAD"  -L ""  -L "R^0" \ | 
 | 			L-three    empty  R-three && | 
 | 		test_cmp three L-three | 
 | 	) | 
 | ' | 
 |  | 
 | # Testcase rename/rename(1to2) of a binary file | 
 | #   Commit O: orig | 
 | #   Commit A: orig-A | 
 | #   Commit B: orig-B | 
 | #   Expected: CONFLICT(rename/rename) message, three unstaged entries in the | 
 | #             index, and contents of orig-[AB] at path orig-[AB] | 
 | test_setup_rename_rename_1_to_2_binary () { | 
 | 	git init rename_rename_1_to_2_binary && | 
 | 	( | 
 | 		cd rename_rename_1_to_2_binary && | 
 |  | 
 | 		echo '* binary' >.gitattributes && | 
 | 		git add .gitattributes && | 
 |  | 
 | 		test_seq 1 10 >orig && | 
 | 		git add orig && | 
 | 		git commit -m orig && | 
 |  | 
 | 		git branch A && | 
 | 		git branch B && | 
 |  | 
 | 		git checkout A && | 
 | 		git mv orig orig-A && | 
 | 		test_seq 1 11 >orig-A && | 
 | 		git add orig-A && | 
 | 		git commit -m orig-A && | 
 |  | 
 | 		git checkout B && | 
 | 		git mv orig orig-B && | 
 | 		test_seq 0 10 >orig-B && | 
 | 		git add orig-B && | 
 | 		git commit -m orig-B | 
 |  | 
 | 	) | 
 | } | 
 |  | 
 | test_expect_success 'rename/rename(1to2) with a binary file' ' | 
 | 	test_setup_rename_rename_1_to_2_binary && | 
 | 	( | 
 | 		cd rename_rename_1_to_2_binary && | 
 |  | 
 | 		git checkout A^0 && | 
 |  | 
 | 		test_must_fail git merge -s recursive B^0 && | 
 |  | 
 | 		# Make sure the index has the right number of entries | 
 | 		git ls-files -s >actual && | 
 | 		test_line_count = 4 actual && | 
 |  | 
 | 		git rev-parse A:orig-A B:orig-B >expect && | 
 | 		git hash-object orig-A orig-B >actual && | 
 | 		test_cmp expect actual | 
 | 	) | 
 | ' | 
 |  | 
 | test_done |