Skip to content

Commit abbd1d9

Browse files
committed
Merge branch 'en/merge-rename-rename-worktree-fix'
When a binary file gets modified and renamed on both sides of history to different locations, both files would be written to the working tree but both would have the contents from "ours". This has been corrected so that the path from each side gets their original content. * en/merge-rename-rename-worktree-fix: merge-recursive: fix rename/rename(1to2) for working tree with a binary
2 parents 7b304ab + 95983da commit abbd1d9

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

merge-recursive.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,6 +1750,18 @@ static int handle_rename_rename_1to2(struct merge_options *opt,
17501750
return -1;
17511751
}
17521752

1753+
if (!mfi.clean && mfi.blob.mode == a->mode &&
1754+
oideq(&mfi.blob.oid, &a->oid)) {
1755+
/*
1756+
* Getting here means we were attempting to merge a binary
1757+
* blob. Since we can't merge binaries, the merge algorithm
1758+
* just takes one side. But we don't want to copy the
1759+
* contents of one side to both paths; we'd rather use the
1760+
* original content at the given path for each path.
1761+
*/
1762+
oidcpy(&mfi.blob.oid, &b->oid);
1763+
mfi.blob.mode = b->mode;
1764+
}
17531765
add = &ci->ren2->dst_entry->stages[flip_stage(3)];
17541766
if (is_valid(add)) {
17551767
add->path = mfi.blob.path = b->path;

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,4 +1379,59 @@ test_expect_success 'check nested conflicts from rename/rename(2to1)' '
13791379
)
13801380
'
13811381

1382+
# Testcase rename/rename(1to2) of a binary file
1383+
# Commit O: orig
1384+
# Commit A: orig-A
1385+
# Commit B: orig-B
1386+
# Expected: CONFLICT(rename/rename) message, three unstaged entries in the
1387+
# index, and contents of orig-[AB] at path orig-[AB]
1388+
test_setup_rename_rename_1_to_2_binary () {
1389+
test_create_repo rename_rename_1_to_2_binary &&
1390+
(
1391+
cd rename_rename_1_to_2_binary &&
1392+
1393+
echo '* binary' >.gitattributes &&
1394+
git add .gitattributes &&
1395+
1396+
test_seq 1 10 >orig &&
1397+
git add orig &&
1398+
git commit -m orig &&
1399+
1400+
git branch A &&
1401+
git branch B &&
1402+
1403+
git checkout A &&
1404+
git mv orig orig-A &&
1405+
test_seq 1 11 >orig-A &&
1406+
git add orig-A &&
1407+
git commit -m orig-A &&
1408+
1409+
git checkout B &&
1410+
git mv orig orig-B &&
1411+
test_seq 0 10 >orig-B &&
1412+
git add orig-B &&
1413+
git commit -m orig-B
1414+
1415+
)
1416+
}
1417+
1418+
test_expect_success 'rename/rename(1to2) with a binary file' '
1419+
test_setup_rename_rename_1_to_2_binary &&
1420+
(
1421+
cd rename_rename_1_to_2_binary &&
1422+
1423+
git checkout A^0 &&
1424+
1425+
test_must_fail git merge -s recursive B^0 &&
1426+
1427+
# Make sure the index has the right number of entries
1428+
git ls-files -s >actual &&
1429+
test_line_count = 4 actual &&
1430+
1431+
git rev-parse A:orig-A B:orig-B >expect &&
1432+
git hash-object orig-A orig-B >actual &&
1433+
test_cmp expect actual
1434+
)
1435+
'
1436+
13821437
test_done

0 commit comments

Comments
 (0)