Merge branch 'jc/merge-detached-head-name'
The default merge message prepared by "git merge" records the name of the current branch; the name can be overridden with a new option to allow users to pretend a merge is made on a different branch. * jc/merge-detached-head-name: merge: allow to pretend a merge is made into a different branchmaint
						commit
						bb14cfdfd7
					
				|  | @ -9,7 +9,7 @@ git-fmt-merge-msg - Produce a merge commit message | |||
| SYNOPSIS | ||||
| -------- | ||||
| [verse] | ||||
| 'git fmt-merge-msg' [-m <message>] [--log[=<n>] | --no-log] | ||||
| 'git fmt-merge-msg' [-m <message>] [--into-name <branch>] [--log[=<n>] | --no-log] | ||||
| 'git fmt-merge-msg' [-m <message>] [--log[=<n>] | --no-log] -F <file> | ||||
|  | ||||
| DESCRIPTION | ||||
|  | @ -44,6 +44,10 @@ OPTIONS | |||
| 	Use <message> instead of the branch names for the first line | ||||
| 	of the log message.  For use with `--log`. | ||||
|  | ||||
| --into-name <branch>:: | ||||
| 	Prepare the merge message as if merging to the branch `<branch>`, | ||||
| 	instead of the name of the real branch to which the merge is made. | ||||
|  | ||||
| -F <file>:: | ||||
| --file <file>:: | ||||
| 	Take the list of merged objects from <file> instead of | ||||
|  |  | |||
|  | @ -12,7 +12,8 @@ SYNOPSIS | |||
| 'git merge' [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] | ||||
| 	[--no-verify] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] | ||||
| 	[--[no-]allow-unrelated-histories] | ||||
| 	[--[no-]rerere-autoupdate] [-m <msg>] [-F <file>] [<commit>...] | ||||
| 	[--[no-]rerere-autoupdate] [-m <msg>] [-F <file>] | ||||
| 	[--into-name <branch>] [<commit>...] | ||||
| 'git merge' (--continue | --abort | --quit) | ||||
|  | ||||
| DESCRIPTION | ||||
|  | @ -76,6 +77,11 @@ The 'git fmt-merge-msg' command can be | |||
| used to give a good default for automated 'git merge' | ||||
| invocations. The automated message can include the branch description. | ||||
|  | ||||
| --into-name <branch>:: | ||||
| 	Prepare the default merge message as if merging to the branch | ||||
| 	`<branch>`, instead of the name of the real branch to which | ||||
| 	the merge is made. | ||||
|  | ||||
| -F <file>:: | ||||
| --file=<file>:: | ||||
| 	Read the commit message to be used for the merge commit (in | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) | |||
| { | ||||
| 	const char *inpath = NULL; | ||||
| 	const char *message = NULL; | ||||
| 	char *into_name = NULL; | ||||
| 	int shortlog_len = -1; | ||||
| 	struct option options[] = { | ||||
| 		{ OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"), | ||||
|  | @ -23,6 +24,8 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) | |||
| 		  DEFAULT_MERGE_LOG_LEN }, | ||||
| 		OPT_STRING('m', "message", &message, N_("text"), | ||||
| 			N_("use <text> as start of message")), | ||||
| 		OPT_STRING(0, "into-name", &into_name, N_("name"), | ||||
| 			   N_("use <name> instead of the real target branch")), | ||||
| 		OPT_FILENAME('F', "file", &inpath, N_("file to read from")), | ||||
| 		OPT_END() | ||||
| 	}; | ||||
|  | @ -56,6 +59,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) | |||
| 	opts.add_title = !message; | ||||
| 	opts.credit_people = 1; | ||||
| 	opts.shortlog_len = shortlog_len; | ||||
| 	opts.into_name = into_name; | ||||
|  | ||||
| 	ret = fmt_merge_msg(&input, &output, &opts); | ||||
| 	if (ret) | ||||
|  |  | |||
|  | @ -87,6 +87,7 @@ static int signoff; | |||
| static const char *sign_commit; | ||||
| static int autostash; | ||||
| static int no_verify; | ||||
| static char *into_name; | ||||
|  | ||||
| static struct strategy all_strategy[] = { | ||||
| 	{ "recursive",  NO_TRIVIAL }, | ||||
|  | @ -286,6 +287,8 @@ static struct option builtin_merge_options[] = { | |||
| 	{ OPTION_LOWLEVEL_CALLBACK, 'F', "file", &merge_msg, N_("path"), | ||||
| 		N_("read message from file"), PARSE_OPT_NONEG, | ||||
| 		NULL, 0, option_read_message }, | ||||
| 	OPT_STRING(0, "into-name", &into_name, N_("name"), | ||||
| 		   N_("use <name> instead of the real target")), | ||||
| 	OPT__VERBOSITY(&verbosity), | ||||
| 	OPT_BOOL(0, "abort", &abort_current_merge, | ||||
| 		N_("abort the current in-progress merge")), | ||||
|  | @ -1121,6 +1124,7 @@ static void prepare_merge_message(struct strbuf *merge_names, struct strbuf *mer | |||
| 	opts.add_title = !have_message; | ||||
| 	opts.shortlog_len = shortlog_len; | ||||
| 	opts.credit_people = (0 < option_edit); | ||||
| 	opts.into_name = into_name; | ||||
|  | ||||
| 	fmt_merge_msg(merge_names, merge_msg, &opts); | ||||
| 	if (merge_msg->len) | ||||
|  |  | |||
|  | @ -650,12 +650,15 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out, | |||
|  | ||||
| 	memset(&merge_parents, 0, sizeof(merge_parents)); | ||||
|  | ||||
| 	/* get current branch */ | ||||
| 	/* learn the commit that we merge into and the current branch name */ | ||||
| 	current_branch = current_branch_to_free = | ||||
| 		resolve_refdup("HEAD", RESOLVE_REF_READING, &head_oid, NULL); | ||||
| 	if (!current_branch) | ||||
| 		die("No current branch"); | ||||
| 	if (starts_with(current_branch, "refs/heads/")) | ||||
|  | ||||
| 	if (opts->into_name) | ||||
| 		current_branch = opts->into_name; | ||||
| 	else if (starts_with(current_branch, "refs/heads/")) | ||||
| 		current_branch += 11; | ||||
|  | ||||
| 	find_merge_parents(&merge_parents, in, &head_oid); | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ struct fmt_merge_msg_opts { | |||
| 	unsigned add_title:1, | ||||
| 		credit_people:1; | ||||
| 	int shortlog_len; | ||||
| 	const char *into_name; | ||||
| }; | ||||
|  | ||||
| extern int merge_log_config; | ||||
|  |  | |||
|  | @ -633,7 +633,35 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' | |||
| 	test_cmp expected .git/MERGE_MSG | ||||
| ' | ||||
|  | ||||
| test_expect_success 'merge --into-name=<name>' ' | ||||
| 	test_when_finished "git checkout main" && | ||||
| 	git checkout -B side main && | ||||
| 	git commit --allow-empty -m "One step ahead" && | ||||
|  | ||||
| 	git checkout --detach main && | ||||
| 	git merge --no-ff side && | ||||
| 	git show -s --format="%s" >full.0 && | ||||
| 	head -n1 full.0 >actual && | ||||
| 	# expect that HEAD is shown as-is | ||||
| 	grep -e "Merge branch .side. into HEAD$" actual && | ||||
|  | ||||
| 	git reset --hard main && | ||||
| 	git merge --no-ff --into-name=main side && | ||||
| 	git show -s --format="%s" >full.1 && | ||||
| 	head -n1 full.1 >actual && | ||||
| 	# expect that we pretend to be merging to main, that is suppressed | ||||
| 	grep -e "Merge branch .side.$" actual && | ||||
|  | ||||
| 	git checkout -b throwaway main && | ||||
| 	git merge --no-ff --into-name=main side && | ||||
| 	git show -s --format="%s" >full.2 && | ||||
| 	head -n1 full.2 >actual && | ||||
| 	# expect that we pretend to be merging to main, that is suppressed | ||||
| 	grep -e "Merge branch .side.$" actual | ||||
| ' | ||||
|  | ||||
| test_expect_success 'merge.suppressDest configuration' ' | ||||
| 	test_when_finished "git checkout main" && | ||||
| 	git checkout -B side main && | ||||
| 	git commit --allow-empty -m "One step ahead" && | ||||
| 	git checkout main && | ||||
|  | @ -650,7 +678,19 @@ test_expect_success 'merge.suppressDest configuration' ' | |||
| 	git -c merge.suppressDest="ma?*[rn]" fmt-merge-msg <.git/FETCH_HEAD >full.3 && | ||||
| 	head -n1 full.3 >actual && | ||||
| 	grep -e "Merge branch .side." actual && | ||||
| 	! grep -e " into main$" actual | ||||
| 	! grep -e " into main$" actual && | ||||
|  | ||||
| 	git checkout --detach HEAD && | ||||
| 	git -c merge.suppressDest="main" fmt-merge-msg <.git/FETCH_HEAD >full.4 && | ||||
| 	head -n1 full.4 >actual && | ||||
| 	grep -e "Merge branch .side. into HEAD$" actual && | ||||
|  | ||||
| 	git -c merge.suppressDest="main" fmt-merge-msg \ | ||||
| 		--into-name=main <.git/FETCH_HEAD >full.5 && | ||||
| 	head -n1 full.5 >actual && | ||||
| 	grep -e "Merge branch .side." actual && | ||||
| 	! grep -e " into main$" actual && | ||||
| 	! grep -e " into HEAD$" actual | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano