git-remote-ext
[gitweb.git] / builtin / fmt-merge-msg.c
index 601201264ed0cd6f331c6517efa3e6a1504002bd..e7e12eea250691a2c0d70964d1fffea0923dd292 100644 (file)
@@ -7,7 +7,7 @@
 #include "string-list.h"
 
 static const char * const fmt_merge_msg_usage[] = {
-       "git fmt-merge-msg [--log|--no-log] [--file <file>]",
+       "git fmt-merge-msg [-m <message>] [--log|--no-log] [--file <file>]",
        NULL
 };
 
@@ -38,8 +38,8 @@ void init_src_data(struct src_data *data)
        data->generic.strdup_strings = 1;
 }
 
-static struct string_list srcs = { NULL, 0, 0, 1 };
-static struct string_list origins = { NULL, 0, 0, 1 };
+static struct string_list srcs = STRING_LIST_INIT_DUP;
+static struct string_list origins = STRING_LIST_INIT_DUP;
 
 static int handle_line(char *line)
 {
@@ -146,7 +146,7 @@ static void shortlog(const char *name, unsigned char *sha1,
        int i, count = 0;
        struct commit *commit;
        struct object *branch;
-       struct string_list subjects = { NULL, 0, 0, 1 };
+       struct string_list subjects = STRING_LIST_INIT_DUP;
        int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;
        struct strbuf sb = STRBUF_INIT;
 
@@ -202,35 +202,10 @@ static void shortlog(const char *name, unsigned char *sha1,
        string_list_clear(&subjects, 0);
 }
 
-int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
-       int limit = 20, i = 0, pos = 0;
+static void do_fmt_merge_msg_title(struct strbuf *out,
+       const char *current_branch) {
+       int i = 0;
        char *sep = "";
-       unsigned char head_sha1[20];
-       const char *current_branch;
-
-       /* get current branch */
-       current_branch = resolve_ref("HEAD", head_sha1, 1, NULL);
-       if (!current_branch)
-               die("No current branch");
-       if (!prefixcmp(current_branch, "refs/heads/"))
-               current_branch += 11;
-
-       /* get a line */
-       while (pos < in->len) {
-               int len;
-               char *newline, *p = in->buf + pos;
-
-               newline = strchr(p, '\n');
-               len = newline ? newline - p : strlen(p);
-               pos += len + !!newline;
-               i++;
-               p[len] = 0;
-               if (handle_line(p))
-                       die ("Error in line %d: %.*s", i, len, p);
-       }
-
-       if (!srcs.nr)
-               return 0;
 
        strbuf_addstr(out, "Merge ");
        for (i = 0; i < srcs.nr; i++) {
@@ -278,6 +253,40 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
                strbuf_addch(out, '\n');
        else
                strbuf_addf(out, " into %s\n", current_branch);
+}
+
+static int do_fmt_merge_msg(int merge_title, int merge_summary,
+       struct strbuf *in, struct strbuf *out) {
+       int limit = 20, i = 0, pos = 0;
+       unsigned char head_sha1[20];
+       const char *current_branch;
+
+       /* get current branch */
+       current_branch = resolve_ref("HEAD", head_sha1, 1, NULL);
+       if (!current_branch)
+               die("No current branch");
+       if (!prefixcmp(current_branch, "refs/heads/"))
+               current_branch += 11;
+
+       /* get a line */
+       while (pos < in->len) {
+               int len;
+               char *newline, *p = in->buf + pos;
+
+               newline = strchr(p, '\n');
+               len = newline ? newline - p : strlen(p);
+               pos += len + !!newline;
+               i++;
+               p[len] = 0;
+               if (handle_line(p))
+                       die ("Error in line %d: %.*s", i, len, p);
+       }
+
+       if (!srcs.nr)
+               return 0;
+
+       if (merge_title)
+               do_fmt_merge_msg_title(out, current_branch);
 
        if (merge_summary) {
                struct commit *head;
@@ -289,6 +298,9 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
                rev.ignore_merges = 1;
                rev.limited = 1;
 
+               if (suffixcmp(out->buf, "\n"))
+                       strbuf_addch(out, '\n');
+
                for (i = 0; i < origins.nr; i++)
                        shortlog(origins.items[i].string, origins.items[i].util,
                                        head, &rev, limit, out);
@@ -296,14 +308,25 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
        return 0;
 }
 
+int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
+       return do_fmt_merge_msg(1, merge_summary, in, out);
+}
+
+int fmt_merge_msg_shortlog(struct strbuf *in, struct strbuf *out) {
+       return do_fmt_merge_msg(0, 1, in, out);
+}
+
 int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 {
        const char *inpath = NULL;
+       const char *message = NULL;
        struct option options[] = {
                OPT_BOOLEAN(0, "log",     &merge_summary, "populate log with the shortlog"),
                { OPTION_BOOLEAN, 0, "summary", &merge_summary, NULL,
                  "alias for --log (deprecated)",
                  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
+               OPT_STRING('m', "message", &message, "text",
+                       "use <text> as start of message"),
                OPT_FILENAME('F', "file", &inpath, "file to read from"),
                OPT_END()
        };
@@ -317,6 +340,12 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
                             0);
        if (argc > 0)
                usage_with_options(fmt_merge_msg_usage, options);
+       if (message && !merge_summary) {
+               char nl = '\n';
+               write_in_full(STDOUT_FILENO, message, strlen(message));
+               write_in_full(STDOUT_FILENO, &nl, 1);
+               return 0;
+       }
 
        if (inpath && strcmp(inpath, "-")) {
                in = fopen(inpath, "r");
@@ -326,7 +355,12 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 
        if (strbuf_read(&input, fileno(in), 0) < 0)
                die_errno("could not read input file");
-       ret = fmt_merge_msg(merge_summary, &input, &output);
+       if (message) {
+               strbuf_addstr(&output, message);
+               ret = fmt_merge_msg_shortlog(&input, &output);
+       } else {
+               ret = fmt_merge_msg(merge_summary, &input, &output);
+       }
        if (ret)
                return ret;
        write_in_full(STDOUT_FILENO, output.buf, output.len);