Commit 58a1ece4 authored by Justin Frankel's avatar Justin Frankel Committed by Junio C Hamano

merge-recursive --patience

Teach the merge-recursive strategy a --patience option to use the
"patience diff" algorithm, which tends to improve results when
cherry-picking a patch that reorders functions at the same time as
refactoring them.

To support this, struct merge_options and ll_merge_options gain an
xdl_opts member, so programs can use arbitrary xdiff flags (think
"XDF_IGNORE_WHITESPACE") in a git-aware merge.

git merge and git rebase can be passed the -Xpatience option to
use this.

[jn: split from --ignore-space patch; with documentation]
Signed-off-by: default avatarJustin Frankel <[email protected]>
Signed-off-by: default avatarJonathan Nieder <[email protected]>
Signed-off-by: default avatarJunio C Hamano <[email protected]>
parent 712516bc
......@@ -40,6 +40,13 @@ the other tree did, declaring 'our' history contains all that happened in it.
This is opposite of 'ours'.
With this option, 'merge-recursive' spends a little extra time
to avoid mismerges that sometimes occur due to unimportant
matching lines (e.g., braces from distinct functions). Use
this when the branches to be merged have diverged wildly.
See also linkgit:git-diff[1] `--patience`.
This runs a virtual check-out and check-in of all three stages
of a file when resolving a three-way merge. This option is
......@@ -2,6 +2,7 @@
#include "commit.h"
#include "tag.h"
#include "merge-recursive.h"
#include "xdiff-interface.h"
static const char *better_branch_name(const char *branch)
......@@ -86,6 +86,7 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
memset(&xmp, 0, sizeof(xmp));
xmp.level = XDL_MERGE_ZEALOUS;
xmp.favor = opts->variant;
xmp.xpp.flags = opts->xdl_opts;
if (git_xmerge_style >= 0) = git_xmerge_style;
if (marker_size > 0)
......@@ -9,6 +9,7 @@ struct ll_merge_options {
unsigned virtual_ancestor : 1;
unsigned variant : 2; /* favor ours, favor theirs, or union merge */
unsigned renormalize : 1;
long xdl_opts;
int ll_merge(mmbuffer_t *result_buf,
......@@ -613,6 +613,7 @@ static int merge_3way(struct merge_options *o,
int merge_status;
ll_opts.renormalize = o->renormalize;
ll_opts.xdl_opts = o->xdl_opts;
if (o->call_depth) {
ll_opts.virtual_ancestor = 1;
......@@ -1512,6 +1513,8 @@ int parse_merge_opt(struct merge_options *o, const char *s)
o->subtree_shift = "";
else if (!prefixcmp(s, "subtree="))
o->subtree_shift = s + strlen("subtree=");
else if (!strcmp(s, "patience"))
o->xdl_opts |= XDF_PATIENCE_DIFF;
else if (!strcmp(s, "renormalize"))
o->renormalize = 1;
else if (!strcmp(s, "no-renormalize"))
......@@ -15,6 +15,7 @@ struct merge_options {
const char *subtree_shift;
unsigned buffer_output : 1;
unsigned renormalize : 1;
long xdl_opts;
int verbosity;
int diff_rename_limit;
int merge_rename_limit;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment