Merge branch 'jc/ll-merge-binary-ours' into maint
* jc/ll-merge-binary-ours: ll-merge: warn about inability to merge binary files only when we can't attr: "binary" attribute should choose built-in "binary" merge driver merge: teach -Xours/-Xtheirs to binary ll-merge driver
This commit is contained in:
commit
8c4bcd34bd
@ -932,7 +932,7 @@ file at the toplevel (i.e. not in any subdirectory). The built-in
|
|||||||
macro attribute "binary" is equivalent to:
|
macro attribute "binary" is equivalent to:
|
||||||
|
|
||||||
------------
|
------------
|
||||||
[attr]binary -diff -text
|
[attr]binary -diff -merge -text
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,13 +32,14 @@ ours;;
|
|||||||
This option forces conflicting hunks to be auto-resolved cleanly by
|
This option forces conflicting hunks to be auto-resolved cleanly by
|
||||||
favoring 'our' version. Changes from the other tree that do not
|
favoring 'our' version. Changes from the other tree that do not
|
||||||
conflict with our side are reflected to the merge result.
|
conflict with our side are reflected to the merge result.
|
||||||
|
For a binary file, the entire contents are taken from our side.
|
||||||
+
|
+
|
||||||
This should not be confused with the 'ours' merge strategy, which does not
|
This should not be confused with the 'ours' merge strategy, which does not
|
||||||
even look at what the other tree contains at all. It discards everything
|
even look at what the other tree contains at all. It discards everything
|
||||||
the other tree did, declaring 'our' history contains all that happened in it.
|
the other tree did, declaring 'our' history contains all that happened in it.
|
||||||
|
|
||||||
theirs;;
|
theirs;;
|
||||||
This is opposite of 'ours'.
|
This is the opposite of 'ours'.
|
||||||
|
|
||||||
patience;;
|
patience;;
|
||||||
With this option, 'merge-recursive' spends a little extra time
|
With this option, 'merge-recursive' spends a little extra time
|
||||||
|
2
attr.c
2
attr.c
@ -306,7 +306,7 @@ static void free_attr_elem(struct attr_stack *e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char *builtin_attr[] = {
|
static const char *builtin_attr[] = {
|
||||||
"[attr]binary -diff -text",
|
"[attr]binary -diff -merge -text",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
32
ll-merge.c
32
ll-merge.c
@ -35,7 +35,7 @@ struct ll_merge_driver {
|
|||||||
*/
|
*/
|
||||||
static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
|
static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
|
||||||
mmbuffer_t *result,
|
mmbuffer_t *result,
|
||||||
const char *path_unused,
|
const char *path,
|
||||||
mmfile_t *orig, const char *orig_name,
|
mmfile_t *orig, const char *orig_name,
|
||||||
mmfile_t *src1, const char *name1,
|
mmfile_t *src1, const char *name1,
|
||||||
mmfile_t *src2, const char *name2,
|
mmfile_t *src2, const char *name2,
|
||||||
@ -46,16 +46,34 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused,
|
|||||||
assert(opts);
|
assert(opts);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The tentative merge result is "ours" for the final round,
|
* The tentative merge result is the or common ancestor for an internal merge.
|
||||||
* or common ancestor for an internal merge. Still return
|
|
||||||
* "conflicted merge" status.
|
|
||||||
*/
|
*/
|
||||||
stolen = opts->virtual_ancestor ? orig : src1;
|
if (opts->virtual_ancestor) {
|
||||||
|
stolen = orig;
|
||||||
|
} else {
|
||||||
|
switch (opts->variant) {
|
||||||
|
default:
|
||||||
|
warning("Cannot merge binary files: %s (%s vs. %s)",
|
||||||
|
path, name1, name2);
|
||||||
|
/* fallthru */
|
||||||
|
case XDL_MERGE_FAVOR_OURS:
|
||||||
|
stolen = src1;
|
||||||
|
break;
|
||||||
|
case XDL_MERGE_FAVOR_THEIRS:
|
||||||
|
stolen = src2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result->ptr = stolen->ptr;
|
result->ptr = stolen->ptr;
|
||||||
result->size = stolen->size;
|
result->size = stolen->size;
|
||||||
stolen->ptr = NULL;
|
stolen->ptr = NULL;
|
||||||
return 1;
|
|
||||||
|
/*
|
||||||
|
* With -Xtheirs or -Xours, we have cleanly merged;
|
||||||
|
* otherwise we got a conflict.
|
||||||
|
*/
|
||||||
|
return (opts->variant ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
|
static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
|
||||||
@ -73,8 +91,6 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
|
|||||||
if (buffer_is_binary(orig->ptr, orig->size) ||
|
if (buffer_is_binary(orig->ptr, orig->size) ||
|
||||||
buffer_is_binary(src1->ptr, src1->size) ||
|
buffer_is_binary(src1->ptr, src1->size) ||
|
||||||
buffer_is_binary(src2->ptr, src2->size)) {
|
buffer_is_binary(src2->ptr, src2->size)) {
|
||||||
warning("Cannot merge binary files: %s (%s vs. %s)",
|
|
||||||
path, name1, name2);
|
|
||||||
return ll_binary_merge(drv_unused, result,
|
return ll_binary_merge(drv_unused, result,
|
||||||
path,
|
path,
|
||||||
orig, orig_name,
|
orig, orig_name,
|
||||||
|
@ -53,7 +53,19 @@ test_expect_success 'recursive favouring ours' '
|
|||||||
! grep 1 file
|
! grep 1 file
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'pull with -X' '
|
test_expect_success 'binary file with -Xours/-Xtheirs' '
|
||||||
|
echo file binary >.gitattributes &&
|
||||||
|
|
||||||
|
git reset --hard master &&
|
||||||
|
git merge -s recursive -X theirs side &&
|
||||||
|
git diff --exit-code side HEAD -- file &&
|
||||||
|
|
||||||
|
git reset --hard master &&
|
||||||
|
git merge -s recursive -X ours side &&
|
||||||
|
git diff --exit-code master HEAD -- file
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'pull passes -X to underlying merge' '
|
||||||
git reset --hard master && git pull -s recursive -Xours . side &&
|
git reset --hard master && git pull -s recursive -Xours . side &&
|
||||||
git reset --hard master && git pull -s recursive -X ours . side &&
|
git reset --hard master && git pull -s recursive -X ours . side &&
|
||||||
git reset --hard master && git pull -s recursive -Xtheirs . side &&
|
git reset --hard master && git pull -s recursive -Xtheirs . side &&
|
||||||
|
Loading…
Reference in New Issue
Block a user