merge-recursive --renormalize

Teach "git merge-recursive" a --renormalize option to enable the
merge.renormalize configuration.  The --no-renormalize option can
be used to override it in the negative.

So in the future, you might be able to, e.g.:

	git checkout -m -Xrenormalize otherbranch

or

	git revert -Xrenormalize otherpatch

or

	git pull --rebase -Xrenormalize

The bad part: merge.renormalize is still not honored for most
commands.  And it reveals lots of places that -X has not been plumbed
in (so we get "git merge -Xrenormalize" but not much else).

NEEDSWORK: tests

Cc: Eyvind Bernhardsen <eyvind.bernhardsen@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jonathan Nieder 2010-08-05 06:32:41 -05:00 committed by Junio C Hamano
parent ff8ba59e7b
commit 7610fa57e6
8 changed files with 45 additions and 8 deletions

View File

@ -40,6 +40,18 @@ the other tree did, declaring 'our' history contains all that happened in it.
theirs;;
This is opposite of 'ours'.
renormalize;;
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
meant to be used when merging branches with different clean
filters or end-of-line normalization rules. See "Merging
branches with differing checkin/checkout attributes" in
linkgit:gitattributes[5] for details.
no-renormalize;;
Disables the `renormalize` option. This overrides the
`merge.renormalize` configuration variable.
subtree[=path];;
This option is a more advanced form of 'subtree' strategy, where
the strategy makes a guess on how two trees must be shifted to

View File

@ -437,6 +437,13 @@ static int merge_working_tree(struct checkout_opts *opts,
*/
add_files_to_cache(NULL, NULL, 0);
/*
* NEEDSWORK: carrying over local changes
* when branches have different end-of-line
* normalization (or clean+smudge rules) is
* a pain; plumb in an option to set
* o.renormalize?
*/
init_merge_options(&o);
o.verbosity = 0;
work = write_tree_from_memory(&o);

View File

@ -45,6 +45,10 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
o.subtree_shift = "";
else if (!prefixcmp(arg+2, "subtree="))
o.subtree_shift = arg + 10;
else if (!strcmp(arg+2, "renormalize"))
o.renormalize = 1;
else if (!strcmp(arg+2, "no-renormalize"))
o.renormalize = 0;
else
die("Unknown option %s", arg);
continue;

View File

@ -54,6 +54,7 @@ static size_t use_strategies_nr, use_strategies_alloc;
static const char **xopts;
static size_t xopts_nr, xopts_alloc;
static const char *branch;
static int option_renormalize;
static int verbosity;
static int allow_rerere_auto;
@ -503,9 +504,8 @@ static int git_merge_config(const char *k, const char *v, void *cb)
return git_config_string(&pull_octopus, k, v);
else if (!strcmp(k, "merge.log") || !strcmp(k, "merge.summary"))
option_log = git_config_bool(k, v);
else if (!strcmp(k, "merge.renormalize")) {
merge_renormalize = git_config_bool(k, v);
}
else if (!strcmp(k, "merge.renormalize"))
option_renormalize = git_config_bool(k, v);
return git_diff_ui_config(k, v, cb);
}
@ -627,6 +627,11 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
if (!strcmp(strategy, "subtree"))
o.subtree_shift = "";
o.renormalize = option_renormalize;
/*
* NEEDSWORK: merge with table in builtin/merge-recursive
*/
for (x = 0; x < xopts_nr; x++) {
if (!strcmp(xopts[x], "ours"))
o.recursive_variant = MERGE_RECURSIVE_OURS;
@ -636,6 +641,10 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
o.subtree_shift = "";
else if (!prefixcmp(xopts[x], "subtree="))
o.subtree_shift = xopts[x]+8;
else if (!strcmp(xopts[x], "renormalize"))
o.renormalize = 1;
else if (!strcmp(xopts[x], "no-renormalize"))
o.renormalize = 0;
else
die("Unknown option for merge-recursive: -X%s", xopts[x]);
}
@ -819,7 +828,7 @@ static int finish_automerge(struct commit_list *common,
return 0;
}
static int suggest_conflicts(void)
static int suggest_conflicts(int renormalizing)
{
FILE *fp;
int pos;
@ -1304,5 +1313,5 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
"stopped before committing as requested\n");
return 0;
} else
return suggest_conflicts();
return suggest_conflicts(option_renormalize);
}

View File

@ -318,6 +318,13 @@ static void do_recursive_merge(struct commit *base, struct commit *next,
index_fd = hold_locked_index(&index_lock, 1);
read_cache();
/*
* NEEDSWORK: cherry-picking between branches with
* different end-of-line normalization is a pain;
* plumb in an option to set o.renormalize?
* (or better: arbitrary -X options)
*/
init_merge_options(&o);
o.ancestor = base ? base_label : "(empty tree)";
o.branch1 = "HEAD";

View File

@ -551,7 +551,6 @@ extern int read_replace_refs;
extern int fsync_object_files;
extern int core_preload_index;
extern int core_apply_sparse_checkout;
extern int merge_renormalize;
enum safe_crlf {
SAFE_CRLF_FALSE = 0,

View File

@ -53,7 +53,6 @@ enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
char *notes_ref_name;
int grafts_replace_parents = 1;
int core_apply_sparse_checkout;
int merge_renormalize;
/* Parallel index stat data preload? */
int core_preload_index = 0;

View File

@ -1486,7 +1486,7 @@ void init_merge_options(struct merge_options *o)
o->buffer_output = 1;
o->diff_rename_limit = -1;
o->merge_rename_limit = -1;
o->renormalize = merge_renormalize;
o->renormalize = 0;
git_config(merge_recursive_config, o);
if (getenv("GIT_MERGE_VERBOSITY"))
o->verbosity =