@@ -48,6 +48,10 @@ OPTIONS
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.
+--from-name <branch>::
+ Prepare the merge message as if merging from the branch `<branch>`,
+ instead of the name of the real branch from which the merge is made.
+
-F <file>::
--file <file>::
Take the list of merged objects from <file> instead of
@@ -82,6 +82,11 @@ invocations. The automated message can include the branch description.
`<branch>`, instead of the name of the real branch to which
the merge is made.
+--from-name <branch>::
+ Prepare the default merge message as if merging from the branch
+ `<branch>`, instead of the name of the real branch from which
+ the merge is made.
+
-F <file>::
--file=<file>::
Read the commit message to be used for the merge commit (in
@@ -13,6 +13,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;
+ char *from_name = NULL;
int shortlog_len = -1;
struct option options[] = {
{ OPTION_INTEGER, 0, "log", &shortlog_len, N_("n"),
@@ -26,6 +27,8 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
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_STRING(0, "from-name", &from_name, N_("name"),
+ N_("use <name> instead of the real source branch")),
OPT_FILENAME('F', "file", &inpath, N_("file to read from")),
OPT_END()
};
@@ -60,6 +63,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
opts.credit_people = 1;
opts.shortlog_len = shortlog_len;
opts.into_name = into_name;
+ opts.from_name = from_name;
ret = fmt_merge_msg(&input, &output, &opts);
if (ret)
@@ -88,6 +88,7 @@ static const char *sign_commit;
static int autostash;
static int no_verify;
static char *into_name;
+static char *from_name;
static struct strategy all_strategy[] = {
{ "recursive", NO_TRIVIAL },
@@ -289,6 +290,8 @@ static struct option builtin_merge_options[] = {
NULL, 0, option_read_message },
OPT_STRING(0, "into-name", &into_name, N_("name"),
N_("use <name> instead of the real target")),
+ OPT_STRING(0, "from-name", &from_name, N_("name"),
+ N_("use <name> instead of the real source")),
OPT__VERBOSITY(&verbosity),
OPT_BOOL(0, "abort", &abort_current_merge,
N_("abort the current in-progress merge")),
@@ -1144,6 +1147,7 @@ static void prepare_merge_message(struct strbuf *merge_names, struct strbuf *mer
opts.shortlog_len = shortlog_len;
opts.credit_people = (0 < option_edit);
opts.into_name = into_name;
+ opts.from_name = from_name;
fmt_merge_msg(merge_names, merge_msg, &opts);
if (merge_msg->len)
@@ -353,6 +353,7 @@ static void shortlog(const char *name,
struct strbuf sb = STRBUF_INIT;
const struct object_id *oid = &origin_data->oid;
int limit = opts->shortlog_len;
+ const char *from_name = opts->from_name ? opts->from_name : name;
branch = deref_tag(the_repository, parse_object(the_repository, oid),
oid_to_hex(oid),
@@ -398,12 +399,12 @@ static void shortlog(const char *name,
if (opts->credit_people)
add_people_info(out, &authors, &committers);
if (count > limit)
- strbuf_addf(out, "\n* %s: (%d commits)\n", name, count);
+ strbuf_addf(out, "\n* %s: (%d commits)\n", from_name, count);
else
- strbuf_addf(out, "\n* %s:\n", name);
+ strbuf_addf(out, "\n* %s:\n", from_name);
if (origin_data->is_local_branch && use_branch_desc)
- add_branch_desc(out, name);
+ add_branch_desc(out, from_name);
for (i = 0; i < subjects.nr; i++)
if (i >= limit)
@@ -441,51 +442,57 @@ static int dest_suppressed(const char *dest_branch)
}
static void fmt_merge_msg_title(struct strbuf *out,
- const char *current_branch)
+ const char *current_branch,
+ const char *into_branch)
{
int i = 0;
char *sep = "";
strbuf_addstr(out, "Merge ");
- for (i = 0; i < srcs.nr; i++) {
- struct src_data *src_data = srcs.items[i].util;
- const char *subsep = "";
- strbuf_addstr(out, sep);
- sep = "; ";
+ if (into_branch) {
+ strbuf_addstr(out, into_branch);
+ } else {
+ for (i = 0; i < srcs.nr; i++) {
+ struct src_data *src_data = srcs.items[i].util;
+ const char *subsep = "";
- if (src_data->head_status == 1) {
- strbuf_addstr(out, srcs.items[i].string);
- continue;
- }
- if (src_data->head_status == 3) {
- subsep = ", ";
- strbuf_addstr(out, "HEAD");
- }
- if (src_data->branch.nr) {
- strbuf_addstr(out, subsep);
- subsep = ", ";
- print_joined("branch ", "branches ", &src_data->branch,
- out);
- }
- if (src_data->r_branch.nr) {
- strbuf_addstr(out, subsep);
- subsep = ", ";
- print_joined("remote-tracking branch ", "remote-tracking branches ",
- &src_data->r_branch, out);
- }
- if (src_data->tag.nr) {
- strbuf_addstr(out, subsep);
- subsep = ", ";
- print_joined("tag ", "tags ", &src_data->tag, out);
- }
- if (src_data->generic.nr) {
- strbuf_addstr(out, subsep);
- print_joined("commit ", "commits ", &src_data->generic,
- out);
+ strbuf_addstr(out, sep);
+ sep = "; ";
+
+ if (src_data->head_status == 1) {
+ strbuf_addstr(out, srcs.items[i].string);
+ continue;
+ }
+ if (src_data->head_status == 3) {
+ subsep = ", ";
+ strbuf_addstr(out, "HEAD");
+ }
+ if (src_data->branch.nr) {
+ strbuf_addstr(out, subsep);
+ subsep = ", ";
+ print_joined("branch ", "branches ", &src_data->branch,
+ out);
+ }
+ if (src_data->r_branch.nr) {
+ strbuf_addstr(out, subsep);
+ subsep = ", ";
+ print_joined("remote-tracking branch ", "remote-tracking branches ",
+ &src_data->r_branch, out);
+ }
+ if (src_data->tag.nr) {
+ strbuf_addstr(out, subsep);
+ subsep = ", ";
+ print_joined("tag ", "tags ", &src_data->tag, out);
+ }
+ if (src_data->generic.nr) {
+ strbuf_addstr(out, subsep);
+ print_joined("commit ", "commits ", &src_data->generic,
+ out);
+ }
+ if (strcmp(".", srcs.items[i].string))
+ strbuf_addf(out, " of %s", srcs.items[i].string);
}
- if (strcmp(".", srcs.items[i].string))
- strbuf_addf(out, " of %s", srcs.items[i].string);
}
if (!dest_suppressed(current_branch))
@@ -678,7 +685,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
}
if (opts->add_title && srcs.nr)
- fmt_merge_msg_title(out, current_branch);
+ fmt_merge_msg_title(out, current_branch, opts->from_name);
if (origins.nr)
fmt_merge_msg_sigs(out);
@@ -10,6 +10,7 @@ struct fmt_merge_msg_opts {
credit_people:1;
int shortlog_len;
const char *into_name;
+ const char *from_name;
};
extern int merge_log_config;
We have a "--into-name" to fake one side of the merge message, but there's no way to fake the from branch that's being merged. The specific case I'm running into is "b4 shazam -M" with shortlogs enabled, which ends up putting a "/tmp/tmp.XXXXXX" as the from branch in the shortlog (the title is already overriden by b4). Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> --- I saw tests were required by the patch submission docs, but I haven't written any. That's both because I don't know how to do so (I haven't done much hacking on git), and because I'm not sure this is useful enough for other people to warrant taking upstream. Happy to do so, but figured I'd send this along this as-is to start. --- Documentation/git-fmt-merge-msg.txt | 4 ++ Documentation/git-merge.txt | 5 ++ builtin/fmt-merge-msg.c | 4 ++ builtin/merge.c | 4 ++ fmt-merge-msg.c | 89 ++++++++++++++++------------- fmt-merge-msg.h | 1 + 6 files changed, 66 insertions(+), 41 deletions(-)