Skip to content

Commit a944af1

Browse files
committed
merge: teach -Xours/-Xtheirs to binary ll-merge driver
The (discouraged) -Xours/-Xtheirs modes of merge are supposed to give a quick and dirty way to come up with a random mixture of cleanly merged parts and punted conflict resolution to take contents from one side in conflicting parts. These options however were only passed down to the low level merge driver for text. Teach the built-in binary merge driver to notice them as well. Signed-off-by: Junio C Hamano <[email protected]>
1 parent d0f1ea6 commit a944af1

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

Documentation/merge-strategies.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@ ours;;
3232
This option forces conflicting hunks to be auto-resolved cleanly by
3333
favoring 'our' version. Changes from the other tree that do not
3434
conflict with our side are reflected to the merge result.
35+
For a binary file, the entire contents are taken from our side.
3536
+
3637
This should not be confused with the 'ours' merge strategy, which does not
3738
even look at what the other tree contains at all. It discards everything
3839
the other tree did, declaring 'our' history contains all that happened in it.
3940

4041
theirs;;
41-
This is opposite of 'ours'.
42+
This is the opposite of 'ours'.
4243

4344
patience;;
4445
With this option, 'merge-recursive' spends a little extra time

ll-merge.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,31 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
4646
assert(opts);
4747

4848
/*
49-
* The tentative merge result is "ours" for the final round,
50-
* or common ancestor for an internal merge. Still return
51-
* "conflicted merge" status.
49+
* The tentative merge result is the or common ancestor for an internal merge.
5250
*/
53-
stolen = opts->virtual_ancestor ? orig : src1;
51+
if (opts->virtual_ancestor) {
52+
stolen = orig;
53+
} else {
54+
switch (opts->variant) {
55+
default:
56+
case XDL_MERGE_FAVOR_OURS:
57+
stolen = src1;
58+
break;
59+
case XDL_MERGE_FAVOR_THEIRS:
60+
stolen = src2;
61+
break;
62+
}
63+
}
5464

5565
result->ptr = stolen->ptr;
5666
result->size = stolen->size;
5767
stolen->ptr = NULL;
58-
return 1;
68+
69+
/*
70+
* With -Xtheirs or -Xours, we have cleanly merged;
71+
* otherwise we got a conflict.
72+
*/
73+
return (opts->variant ? 0 : 1);
5974
}
6075

6176
static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,

t/t6037-merge-ours-theirs.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,19 @@ test_expect_success 'recursive favouring ours' '
5353
! grep 1 file
5454
'
5555

56-
test_expect_success 'pull with -X' '
56+
test_expect_success 'binary file with -Xours/-Xtheirs' '
57+
echo "file -merge" >.gitattributes &&
58+
59+
git reset --hard master &&
60+
git merge -s recursive -X theirs side &&
61+
git diff --exit-code side HEAD -- file &&
62+
63+
git reset --hard master &&
64+
git merge -s recursive -X ours side &&
65+
git diff --exit-code master HEAD -- file
66+
'
67+
68+
test_expect_success 'pull passes -X to underlying merge' '
5769
git reset --hard master && git pull -s recursive -Xours . side &&
5870
git reset --hard master && git pull -s recursive -X ours . side &&
5971
git reset --hard master && git pull -s recursive -Xtheirs . side &&

0 commit comments

Comments
 (0)