All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] merge-recursive: fix rename/rename(1to2) for working tree with a binary
@ 2020-05-13 23:56 Elijah Newren via GitGitGadget
  0 siblings, 0 replies; only message in thread
From: Elijah Newren via GitGitGadget @ 2020-05-13 23:56 UTC (permalink / raw)
  To: git; +Cc: Elijah Newren, Elijah Newren

From: Elijah Newren <newren@gmail.com>

With a rename/rename(1to2) conflict, we attempt to do a three-way merge
of the file contents, so that the correct contents can be placed in the
working tree at both paths.  If the file is a binary, however, no
content merging is possible and we should just use the original version
of the file at each of the paths.

Reported-by: Chunlin Zhang <zhangchunlin@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
---
    merge-recursive: fix rename/rename(1to2) for working tree with a binary
    
    rename/rename(1to2) is unique among our conflict resolutions in that it
    tries to put the as-merged-as-possible contents into two different
    paths, so I think this should be the only code path that needs an update
    for this issue.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-784%2Fnewren%2Frr1to2-binary-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-784/newren/rr1to2-binary-v1
Pull-Request: https://github.com/git/git/pull/784

 merge-recursive.c                    | 12 ++++++
 t/t6042-merge-rename-corner-cases.sh | 55 ++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/merge-recursive.c b/merge-recursive.c
index d92e2acf1ed..36948eafb75 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1750,6 +1750,18 @@ static int handle_rename_rename_1to2(struct merge_options *opt,
 			return -1;
 	}
 
+	if (!mfi.clean && mfi.blob.mode == a->mode &&
+	    oideq(&mfi.blob.oid, &a->oid)) {
+		/*
+		 * Getting here means we were attempting to merge a binary
+		 * blob.  Since we can't merge binaries, the merge algorithm
+		 * just takes one side.  But we don't want to copy the
+		 * contents of one side to both paths; we'd rather use the
+		 * original content at the given path for each path.
+		 */
+		oidcpy(&mfi.blob.oid, &b->oid);
+		mfi.blob.mode = b->mode;
+	}
 	add = &ci->ren2->dst_entry->stages[flip_stage(3)];
 	if (is_valid(add)) {
 		add->path = mfi.blob.path = b->path;
diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh
index b047cf1c1c3..f163893ff97 100755
--- a/t/t6042-merge-rename-corner-cases.sh
+++ b/t/t6042-merge-rename-corner-cases.sh
@@ -1379,4 +1379,59 @@ test_expect_success 'check nested conflicts from rename/rename(2to1)' '
 	)
 '
 
+# 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 () {
+	test_create_repo 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

base-commit: b994622632154fc3b17fb40a38819ad954a5fb88
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-05-13 23:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-05-13 23:56 [PATCH] merge-recursive: fix rename/rename(1to2) for working tree with a binary Elijah Newren via GitGitGadget

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.