Signed-off-by: i.Dark_Templar <darktemplar@xxxxxxxxxxxxxxxxxxxxxxxxx> --- Documentation/config/fmt-merge-msg.txt | 17 ++++-- builtin/fmt-merge-msg.c | 71 ++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/Documentation/config/fmt-merge-msg.txt b/Documentation/config/fmt-merge-msg.txt index 8c12540fa7..3829095222 100644 --- a/Documentation/config/fmt-merge-msg.txt +++ b/Documentation/config/fmt-merge-msg.txt @@ -9,8 +9,15 @@ merge.log:: actual commits that are being merged. Defaults to false, and true is a synonym for 20. -merge.multilineMessage:: - Make default merge commit message multiline. Every merged object - will be written using new line. This should ensure that - commit message wouldn't become one very long line when - there are a lot of merged objects. +merge.messageType:: + Configure default merge commit message type. `original` is used + if no value or an invalid value is set. + + + * `original` keeps old merge commit message format which takes only one line. + * `multiline` switches merge commit message to multiline mode. Every merged object + will be written using new line. This should ensure that commit message + wouldn't become one very long line when there are a lot of merged objects. + * `autoselect`, as it's name implies, selects one of following types + using arbitrary logic. Currently it selects `original` mode for merge + with only one additional object, otherwise switching to `multiline` mode, + but this behaviour may be changed in future without any notice. diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 93d44b59d9..0bc6ce5b05 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -14,13 +14,20 @@ #include "repository.h" #include "commit-reach.h" +enum message_format { + MESSAGE_FORMAT_ORIGINAL = 0, + MESSAGE_FORMAT_MULTILINE = 1, + MESSAGE_FORMAT_AUTOSELECT = 2, + MESSAGE_FORMAT_DEFAULT = MESSAGE_FORMAT_ORIGINAL +}; + static const char * const fmt_merge_msg_usage[] = { N_("git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]"), NULL }; static int use_branch_desc; -static int use_multiline_default_message = 0; +static enum message_format default_message_format = MESSAGE_FORMAT_DEFAULT; int fmt_merge_msg_config(const char *key, const char *value, void *cb) { @@ -33,8 +40,16 @@ int fmt_merge_msg_config(const char *key, const char *value, void *cb) merge_log_config = DEFAULT_MERGE_LOG_LEN; } else if (!strcmp(key, "merge.branchdesc")) { use_branch_desc = git_config_bool(key, value); - } else if (!strcmp(key, "merge.multilinemessage")) { - use_multiline_default_message = git_config_bool(key, value); + } else if (!strcmp(key, "merge.messagetype")) { + if (!value) + return config_error_nonbool(key); + + if (!strcmp(value, "autoselect")) + default_message_format = MESSAGE_FORMAT_AUTOSELECT; + else if (!strcmp(value, "original")) + default_message_format = MESSAGE_FORMAT_ORIGINAL; + else if (!strcmp(value, "multiline")) + default_message_format = MESSAGE_FORMAT_MULTILINE; } else { return git_default_config(key, value, cb); } @@ -525,6 +540,43 @@ static void fmt_merge_msg_title_multiline(struct strbuf *out, } } +static void fmt_merge_msg_title_autoselect(struct strbuf *out, + const char *current_branch) +{ + int i = 0; + int j = 0; + int objects_count = 0; + + for (i = 0; i < srcs.nr; i++) { + struct src_data *src_data = srcs.items[i].util; + + if (src_data->head_status == 1) { + ++objects_count; + continue; + } + if (src_data->head_status == 3) { + ++objects_count; + } + for (j = 0; j < src_data->branch.nr; j++) { + ++objects_count; + } + for (j = 0; j < src_data->r_branch.nr; j++) { + ++objects_count; + } + for (j = 0; j < src_data->tag.nr; j++) { + ++objects_count; + } + for (j = 0; j < src_data->generic.nr; j++) { + ++objects_count; + } + } + + if (objects_count > 1) + fmt_merge_msg_title_multiline(out, current_branch); + else + fmt_merge_msg_title(out, current_branch); +} + static void fmt_tag_signature(struct strbuf *tagbuf, struct strbuf *sig, const char *buf, @@ -693,10 +745,19 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out, } if (opts->add_title && srcs.nr) { - if (!use_multiline_default_message) + switch (default_message_format) { + case MESSAGE_FORMAT_ORIGINAL: fmt_merge_msg_title(out, current_branch); - else + break; + case MESSAGE_FORMAT_MULTILINE: fmt_merge_msg_title_multiline(out, current_branch); + break; + case MESSAGE_FORMAT_AUTOSELECT: + fmt_merge_msg_title_autoselect(out, current_branch); + break; + default: + BUG("merge.messagetype value is not properly processed: %d", (int) default_message_format); + } } if (origins.nr) -- 2.24.1