Merge branch 'bp/merge-rename-config'
With merge.renames configuration set to false, the recursive merge strategy can be told not to spend cycles trying to find renamed paths and merge them accordingly. * bp/merge-rename-config: merge: pass aggressive when rename detection is turned off merge: add merge.renames config setting merge: update documentation for {merge,diff}.renameLimit
This commit is contained in:
commit
6e2ba77bda
@ -112,7 +112,8 @@ diff.orderFile::
|
||||
|
||||
diff.renameLimit::
|
||||
The number of files to consider when performing the copy/rename
|
||||
detection; equivalent to the 'git diff' option `-l`.
|
||||
detection; equivalent to the 'git diff' option `-l`. This setting
|
||||
has no effect if rename detection is turned off.
|
||||
|
||||
diff.renames::
|
||||
Whether and how Git detects renames. If set to "false",
|
||||
|
@ -35,7 +35,13 @@ include::fmt-merge-msg-config.txt[]
|
||||
merge.renameLimit::
|
||||
The number of files to consider when performing rename detection
|
||||
during a merge; if not specified, defaults to the value of
|
||||
diff.renameLimit.
|
||||
diff.renameLimit. This setting has no effect if rename detection
|
||||
is turned off.
|
||||
|
||||
merge.renames::
|
||||
Whether and how Git detects renames. If set to "false",
|
||||
rename detection is disabled. If set to "true", basic rename
|
||||
detection is enabled. Defaults to the value of diff.renames.
|
||||
|
||||
merge.renormalize::
|
||||
Tell Git that canonical representation of files in the
|
||||
|
@ -23,8 +23,9 @@ recursive::
|
||||
causing mismerges by tests done on actual merge commits
|
||||
taken from Linux 2.6 kernel development history.
|
||||
Additionally this can detect and handle merges involving
|
||||
renames. This is the default merge strategy when
|
||||
pulling or merging one branch.
|
||||
renames, but currently cannot make use of detected
|
||||
copies. This is the default merge strategy when pulling
|
||||
or merging one branch.
|
||||
+
|
||||
The 'recursive' strategy can take the following options:
|
||||
|
||||
@ -84,12 +85,14 @@ no-renormalize;;
|
||||
`merge.renormalize` configuration variable.
|
||||
|
||||
no-renames;;
|
||||
Turn off rename detection.
|
||||
Turn off rename detection. This overrides the `merge.renames`
|
||||
configuration variable.
|
||||
See also linkgit:git-diff[1] `--no-renames`.
|
||||
|
||||
find-renames[=<n>];;
|
||||
Turn on rename detection, optionally setting the similarity
|
||||
threshold. This is the default.
|
||||
threshold. This is the default. This overrides the
|
||||
'merge.renames' configuration variable.
|
||||
See also linkgit:git-diff[1] `--find-renames`.
|
||||
|
||||
rename-threshold=<n>;;
|
||||
|
2
diff.c
2
diff.c
@ -177,7 +177,7 @@ static int parse_submodule_params(struct diff_options *options, const char *valu
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int git_config_rename(const char *var, const char *value)
|
||||
int git_config_rename(const char *var, const char *value)
|
||||
{
|
||||
if (!value)
|
||||
return DIFF_DETECT_RENAME;
|
||||
|
1
diff.h
1
diff.h
@ -324,6 +324,7 @@ extern int git_diff_ui_config(const char *var, const char *value, void *cb);
|
||||
extern void diff_setup(struct diff_options *);
|
||||
extern int diff_opt_parse(struct diff_options *, const char **, int, const char *);
|
||||
extern void diff_setup_done(struct diff_options *);
|
||||
extern int git_config_rename(const char *var, const char *value);
|
||||
|
||||
#define DIFF_DETECT_RENAME 1
|
||||
#define DIFF_DETECT_COPY 2
|
||||
|
@ -356,6 +356,7 @@ static int git_merge_trees(struct merge_options *o,
|
||||
o->unpack_opts.fn = threeway_merge;
|
||||
o->unpack_opts.src_index = &the_index;
|
||||
o->unpack_opts.dst_index = &tmp_index;
|
||||
o->unpack_opts.aggressive = !merge_detect_rename(o);
|
||||
setup_unpack_trees_porcelain(&o->unpack_opts, "merge");
|
||||
|
||||
init_tree_desc_from_tree(t+0, common);
|
||||
@ -1603,7 +1604,15 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *o,
|
||||
diff_setup(&opts);
|
||||
opts.flags.recursive = 1;
|
||||
opts.flags.rename_empty = 0;
|
||||
opts.detect_rename = DIFF_DETECT_RENAME;
|
||||
opts.detect_rename = merge_detect_rename(o);
|
||||
/*
|
||||
* We do not have logic to handle the detection of copies. In
|
||||
* fact, it may not even make sense to add such logic: would we
|
||||
* really want a change to a base file to be propagated through
|
||||
* multiple other files by a merge?
|
||||
*/
|
||||
if (opts.detect_rename > DIFF_DETECT_RENAME)
|
||||
opts.detect_rename = DIFF_DETECT_RENAME;
|
||||
opts.rename_limit = o->merge_rename_limit >= 0 ? o->merge_rename_limit :
|
||||
o->diff_rename_limit >= 0 ? o->diff_rename_limit :
|
||||
1000;
|
||||
@ -2643,7 +2652,7 @@ static int handle_renames(struct merge_options *o,
|
||||
ri->head_renames = NULL;
|
||||
ri->merge_renames = NULL;
|
||||
|
||||
if (!o->detect_rename)
|
||||
if (!merge_detect_rename(o))
|
||||
return 1;
|
||||
|
||||
head_pairs = get_diffpairs(o, common, head);
|
||||
@ -3325,9 +3334,18 @@ int merge_recursive_generic(struct merge_options *o,
|
||||
|
||||
static void merge_recursive_config(struct merge_options *o)
|
||||
{
|
||||
char *value = NULL;
|
||||
git_config_get_int("merge.verbosity", &o->verbosity);
|
||||
git_config_get_int("diff.renamelimit", &o->diff_rename_limit);
|
||||
git_config_get_int("merge.renamelimit", &o->merge_rename_limit);
|
||||
if (!git_config_get_string("diff.renames", &value)) {
|
||||
o->diff_detect_rename = git_config_rename("diff.renames", value);
|
||||
free(value);
|
||||
}
|
||||
if (!git_config_get_string("merge.renames", &value)) {
|
||||
o->merge_detect_rename = git_config_rename("merge.renames", value);
|
||||
free(value);
|
||||
}
|
||||
git_config(git_xmerge_config, NULL);
|
||||
}
|
||||
|
||||
@ -3340,7 +3358,8 @@ void init_merge_options(struct merge_options *o)
|
||||
o->diff_rename_limit = -1;
|
||||
o->merge_rename_limit = -1;
|
||||
o->renormalize = 0;
|
||||
o->detect_rename = 1;
|
||||
o->diff_detect_rename = -1;
|
||||
o->merge_detect_rename = -1;
|
||||
merge_recursive_config(o);
|
||||
merge_verbosity = getenv("GIT_MERGE_VERBOSITY");
|
||||
if (merge_verbosity)
|
||||
@ -3391,16 +3410,16 @@ int parse_merge_opt(struct merge_options *o, const char *s)
|
||||
else if (!strcmp(s, "no-renormalize"))
|
||||
o->renormalize = 0;
|
||||
else if (!strcmp(s, "no-renames"))
|
||||
o->detect_rename = 0;
|
||||
o->merge_detect_rename = 0;
|
||||
else if (!strcmp(s, "find-renames")) {
|
||||
o->detect_rename = 1;
|
||||
o->merge_detect_rename = 1;
|
||||
o->rename_score = 0;
|
||||
}
|
||||
else if (skip_prefix(s, "find-renames=", &arg) ||
|
||||
skip_prefix(s, "rename-threshold=", &arg)) {
|
||||
if ((o->rename_score = parse_rename_score(&arg)) == -1 || *arg != 0)
|
||||
return -1;
|
||||
o->detect_rename = 1;
|
||||
o->merge_detect_rename = 1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
@ -18,7 +18,8 @@ struct merge_options {
|
||||
unsigned renormalize : 1;
|
||||
long xdl_opts;
|
||||
int verbosity;
|
||||
int detect_rename;
|
||||
int diff_detect_rename;
|
||||
int merge_detect_rename;
|
||||
int diff_rename_limit;
|
||||
int merge_rename_limit;
|
||||
int rename_score;
|
||||
@ -57,6 +58,12 @@ struct collision_entry {
|
||||
unsigned reported_already:1;
|
||||
};
|
||||
|
||||
static inline int merge_detect_rename(struct merge_options *o)
|
||||
{
|
||||
return o->merge_detect_rename >= 0 ? o->merge_detect_rename :
|
||||
o->diff_detect_rename >= 0 ? o->diff_detect_rename : 1;
|
||||
}
|
||||
|
||||
/* merge_trees() but with recursive ancestor consolidation */
|
||||
int merge_recursive(struct merge_options *o,
|
||||
struct commit *h1,
|
||||
|
@ -309,4 +309,22 @@ test_expect_success 'last wins in --find-renames=<m> --rename-threshold=<n>' '
|
||||
check_threshold_0
|
||||
'
|
||||
|
||||
test_expect_success 'merge.renames disables rename detection' '
|
||||
git read-tree --reset -u HEAD &&
|
||||
git -c merge.renames=false merge-recursive $tail &&
|
||||
check_no_renames
|
||||
'
|
||||
|
||||
test_expect_success 'merge.renames defaults to diff.renames' '
|
||||
git read-tree --reset -u HEAD &&
|
||||
git -c diff.renames=false merge-recursive $tail &&
|
||||
check_no_renames
|
||||
'
|
||||
|
||||
test_expect_success 'merge.renames overrides diff.renames' '
|
||||
git read-tree --reset -u HEAD &&
|
||||
test_must_fail git -c diff.renames=false -c merge.renames=true merge-recursive $tail &&
|
||||
$check_50
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user