Browse Source

merge-recursive: fix rename/rename(1to2) for working tree with a binary

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Elijah Newren 5 years ago committed by Junio C Hamano
parent
commit
95983da6b4
  1. 12
      merge-recursive.c
  2. 55
      t/t6042-merge-rename-corner-cases.sh

12
merge-recursive.c

@ -1750,6 +1750,18 @@ static int handle_rename_rename_1to2(struct merge_options *opt, @@ -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;

55
t/t6042-merge-rename-corner-cases.sh

@ -1379,4 +1379,59 @@ test_expect_success 'check nested conflicts from rename/rename(2to1)' ' @@ -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

Loading…
Cancel
Save