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>maint
							parent
							
								
									ff8ba59e7b
								
							
						
					
					
						commit
						7610fa57e6
					
				|  | @ -40,6 +40,18 @@ the other tree did, declaring 'our' history contains all that happened in it. | ||||||
| theirs;; | theirs;; | ||||||
| 	This is opposite of 'ours'. | 	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];; | subtree[=path];; | ||||||
| 	This option is a more advanced form of 'subtree' strategy, where | 	This option is a more advanced form of 'subtree' strategy, where | ||||||
| 	the strategy makes a guess on how two trees must be shifted to | 	the strategy makes a guess on how two trees must be shifted to | ||||||
|  |  | ||||||
|  | @ -437,6 +437,13 @@ static int merge_working_tree(struct checkout_opts *opts, | ||||||
| 			 */ | 			 */ | ||||||
|  |  | ||||||
| 			add_files_to_cache(NULL, NULL, 0); | 			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); | 			init_merge_options(&o); | ||||||
| 			o.verbosity = 0; | 			o.verbosity = 0; | ||||||
| 			work = write_tree_from_memory(&o); | 			work = write_tree_from_memory(&o); | ||||||
|  |  | ||||||
|  | @ -45,6 +45,10 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix) | ||||||
| 				o.subtree_shift = ""; | 				o.subtree_shift = ""; | ||||||
| 			else if (!prefixcmp(arg+2, "subtree=")) | 			else if (!prefixcmp(arg+2, "subtree=")) | ||||||
| 				o.subtree_shift = arg + 10; | 				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 | 			else | ||||||
| 				die("Unknown option %s", arg); | 				die("Unknown option %s", arg); | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
|  | @ -54,6 +54,7 @@ static size_t use_strategies_nr, use_strategies_alloc; | ||||||
| static const char **xopts; | static const char **xopts; | ||||||
| static size_t xopts_nr, xopts_alloc; | static size_t xopts_nr, xopts_alloc; | ||||||
| static const char *branch; | static const char *branch; | ||||||
|  | static int option_renormalize; | ||||||
| static int verbosity; | static int verbosity; | ||||||
| static int allow_rerere_auto; | 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); | 		return git_config_string(&pull_octopus, k, v); | ||||||
| 	else if (!strcmp(k, "merge.log") || !strcmp(k, "merge.summary")) | 	else if (!strcmp(k, "merge.log") || !strcmp(k, "merge.summary")) | ||||||
| 		option_log = git_config_bool(k, v); | 		option_log = git_config_bool(k, v); | ||||||
| 	else if (!strcmp(k, "merge.renormalize")) { | 	else if (!strcmp(k, "merge.renormalize")) | ||||||
| 		merge_renormalize = git_config_bool(k, v); | 		option_renormalize = git_config_bool(k, v); | ||||||
| 	} |  | ||||||
| 	return git_diff_ui_config(k, v, cb); | 	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")) | 		if (!strcmp(strategy, "subtree")) | ||||||
| 			o.subtree_shift = ""; | 			o.subtree_shift = ""; | ||||||
|  |  | ||||||
|  | 		o.renormalize = option_renormalize; | ||||||
|  |  | ||||||
|  | 		/* | ||||||
|  | 		 * NEEDSWORK: merge with table in builtin/merge-recursive | ||||||
|  | 		 */ | ||||||
| 		for (x = 0; x < xopts_nr; x++) { | 		for (x = 0; x < xopts_nr; x++) { | ||||||
| 			if (!strcmp(xopts[x], "ours")) | 			if (!strcmp(xopts[x], "ours")) | ||||||
| 				o.recursive_variant = MERGE_RECURSIVE_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 = ""; | 				o.subtree_shift = ""; | ||||||
| 			else if (!prefixcmp(xopts[x], "subtree=")) | 			else if (!prefixcmp(xopts[x], "subtree=")) | ||||||
| 				o.subtree_shift = xopts[x]+8; | 				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 | 			else | ||||||
| 				die("Unknown option for merge-recursive: -X%s", xopts[x]); | 				die("Unknown option for merge-recursive: -X%s", xopts[x]); | ||||||
| 		} | 		} | ||||||
|  | @ -819,7 +828,7 @@ static int finish_automerge(struct commit_list *common, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int suggest_conflicts(void) | static int suggest_conflicts(int renormalizing) | ||||||
| { | { | ||||||
| 	FILE *fp; | 	FILE *fp; | ||||||
| 	int pos; | 	int pos; | ||||||
|  | @ -1304,5 +1313,5 @@ int cmd_merge(int argc, const char **argv, const char *prefix) | ||||||
| 			"stopped before committing as requested\n"); | 			"stopped before committing as requested\n"); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} else | 	} else | ||||||
| 		return suggest_conflicts(); | 		return suggest_conflicts(option_renormalize); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -318,6 +318,13 @@ static void do_recursive_merge(struct commit *base, struct commit *next, | ||||||
| 	index_fd = hold_locked_index(&index_lock, 1); | 	index_fd = hold_locked_index(&index_lock, 1); | ||||||
|  |  | ||||||
| 	read_cache(); | 	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); | 	init_merge_options(&o); | ||||||
| 	o.ancestor = base ? base_label : "(empty tree)"; | 	o.ancestor = base ? base_label : "(empty tree)"; | ||||||
| 	o.branch1 = "HEAD"; | 	o.branch1 = "HEAD"; | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										1
									
								
								cache.h
								
								
								
								
							|  | @ -551,7 +551,6 @@ extern int read_replace_refs; | ||||||
| extern int fsync_object_files; | extern int fsync_object_files; | ||||||
| extern int core_preload_index; | extern int core_preload_index; | ||||||
| extern int core_apply_sparse_checkout; | extern int core_apply_sparse_checkout; | ||||||
| extern int merge_renormalize; |  | ||||||
|  |  | ||||||
| enum safe_crlf { | enum safe_crlf { | ||||||
| 	SAFE_CRLF_FALSE = 0, | 	SAFE_CRLF_FALSE = 0, | ||||||
|  |  | ||||||
|  | @ -53,7 +53,6 @@ enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE; | ||||||
| char *notes_ref_name; | char *notes_ref_name; | ||||||
| int grafts_replace_parents = 1; | int grafts_replace_parents = 1; | ||||||
| int core_apply_sparse_checkout; | int core_apply_sparse_checkout; | ||||||
| int merge_renormalize; |  | ||||||
|  |  | ||||||
| /* Parallel index stat data preload? */ | /* Parallel index stat data preload? */ | ||||||
| int core_preload_index = 0; | int core_preload_index = 0; | ||||||
|  |  | ||||||
|  | @ -1486,7 +1486,7 @@ void init_merge_options(struct merge_options *o) | ||||||
| 	o->buffer_output = 1; | 	o->buffer_output = 1; | ||||||
| 	o->diff_rename_limit = -1; | 	o->diff_rename_limit = -1; | ||||||
| 	o->merge_rename_limit = -1; | 	o->merge_rename_limit = -1; | ||||||
| 	o->renormalize = merge_renormalize; | 	o->renormalize = 0; | ||||||
| 	git_config(merge_recursive_config, o); | 	git_config(merge_recursive_config, o); | ||||||
| 	if (getenv("GIT_MERGE_VERBOSITY")) | 	if (getenv("GIT_MERGE_VERBOSITY")) | ||||||
| 		o->verbosity = | 		o->verbosity = | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Jonathan Nieder
						Jonathan Nieder