]> git.ipfire.org Git - thirdparty/git.git/blobdiff - builtin/shortlog.c
post-cocci: adjust comments for recent repo_* migration
[thirdparty/git.git] / builtin / shortlog.c
index 086dfee45aa8be8cc316132ce29bfb93c2ef295a..f287a6acd0325468d0178acbcc97641f7a079957 100644 (file)
@@ -132,7 +132,9 @@ static void read_from_stdin(struct shortlog *log)
                match = committer_match;
                break;
        case SHORTLOG_GROUP_TRAILER:
-               die(_("using --group=trailer with stdin is not supported"));
+               die(_("using %s with stdin is not supported"), "--group=trailer");
+       case SHORTLOG_GROUP_FORMAT:
+               die(_("using %s with stdin is not supported"), "--group=format");
        default:
                BUG("unhandled shortlog group");
        }
@@ -170,11 +172,15 @@ static void insert_records_from_trailers(struct shortlog *log,
        const char *commit_buffer, *body;
        struct strbuf ident = STRBUF_INIT;
 
+       if (!log->trailers.nr)
+               return;
+
        /*
-        * Using format_commit_message("%B") would be simpler here, but
+        * Using repo_format_commit_message("%B") would be simpler here, but
         * this saves us copying the message.
         */
-       commit_buffer = logmsg_reencode(commit, NULL, ctx->output_encoding);
+       commit_buffer = repo_logmsg_reencode(the_repository, commit, NULL,
+                                            ctx->output_encoding);
        body = strstr(commit_buffer, "\n\n");
        if (!body)
                return;
@@ -197,12 +203,38 @@ static void insert_records_from_trailers(struct shortlog *log,
        trailer_iterator_release(&iter);
 
        strbuf_release(&ident);
-       unuse_commit_buffer(commit, commit_buffer);
+       repo_unuse_commit_buffer(the_repository, commit, commit_buffer);
+}
+
+static int shortlog_needs_dedup(const struct shortlog *log)
+{
+       return HAS_MULTI_BITS(log->groups) || log->format.nr > 1 || log->trailers.nr;
+}
+
+static void insert_records_from_format(struct shortlog *log,
+                                      struct strset *dups,
+                                      struct commit *commit,
+                                      struct pretty_print_context *ctx,
+                                      const char *oneline)
+{
+       struct strbuf buf = STRBUF_INIT;
+       struct string_list_item *item;
+
+       for_each_string_list_item(item, &log->format) {
+               strbuf_reset(&buf);
+
+               repo_format_commit_message(the_repository, commit,
+                                          item->string, &buf, ctx);
+
+               if (!shortlog_needs_dedup(log) || strset_add(dups, buf.buf))
+                       insert_one_record(log, buf.buf, oneline);
+       }
+
+       strbuf_release(&buf);
 }
 
 void shortlog_add_commit(struct shortlog *log, struct commit *commit)
 {
-       struct strbuf ident = STRBUF_INIT;
        struct strbuf oneline = STRBUF_INIT;
        struct strset dups = STRSET_INIT;
        struct pretty_print_context ctx = {0};
@@ -211,41 +243,22 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
        ctx.fmt = CMIT_FMT_USERFORMAT;
        ctx.abbrev = log->abbrev;
        ctx.print_email_subject = 1;
-       ctx.date_mode.type = DATE_NORMAL;
+       ctx.date_mode = log->date_mode;
        ctx.output_encoding = get_log_output_encoding();
 
        if (!log->summary) {
                if (log->user_format)
                        pretty_print_commit(&ctx, commit, &oneline);
                else
-                       format_commit_message(commit, "%s", &oneline, &ctx);
+                       repo_format_commit_message(the_repository, commit,
+                                                  "%s", &oneline, &ctx);
        }
        oneline_str = oneline.len ? oneline.buf : "<none>";
 
-       if (log->groups & SHORTLOG_GROUP_AUTHOR) {
-               strbuf_reset(&ident);
-               format_commit_message(commit,
-                                     log->email ? "%aN <%aE>" : "%aN",
-                                     &ident, &ctx);
-               if (!HAS_MULTI_BITS(log->groups) ||
-                   strset_add(&dups, ident.buf))
-                       insert_one_record(log, ident.buf, oneline_str);
-       }
-       if (log->groups & SHORTLOG_GROUP_COMMITTER) {
-               strbuf_reset(&ident);
-               format_commit_message(commit,
-                                     log->email ? "%cN <%cE>" : "%cN",
-                                     &ident, &ctx);
-               if (!HAS_MULTI_BITS(log->groups) ||
-                   strset_add(&dups, ident.buf))
-                       insert_one_record(log, ident.buf, oneline_str);
-       }
-       if (log->groups & SHORTLOG_GROUP_TRAILER) {
-               insert_records_from_trailers(log, &dups, commit, &ctx, oneline_str);
-       }
+       insert_records_from_trailers(log, &dups, commit, &ctx, oneline_str);
+       insert_records_from_format(log, &dups, commit, &ctx, oneline_str);
 
        strset_clear(&dups);
-       strbuf_release(&ident);
        strbuf_release(&oneline);
 }
 
@@ -314,6 +327,7 @@ static int parse_group_option(const struct option *opt, const char *arg, int uns
        if (unset) {
                log->groups = 0;
                string_list_clear(&log->trailers, 0);
+               string_list_clear(&log->format, 0);
        } else if (!strcasecmp(arg, "author"))
                log->groups |= SHORTLOG_GROUP_AUTHOR;
        else if (!strcasecmp(arg, "committer"))
@@ -321,8 +335,15 @@ static int parse_group_option(const struct option *opt, const char *arg, int uns
        else if (skip_prefix(arg, "trailer:", &field)) {
                log->groups |= SHORTLOG_GROUP_TRAILER;
                string_list_append(&log->trailers, field);
-       } else
+       } else if (skip_prefix(arg, "format:", &field)) {
+               log->groups |= SHORTLOG_GROUP_FORMAT;
+               string_list_append(&log->format, field);
+       } else if (strchr(arg, '%')) {
+               log->groups |= SHORTLOG_GROUP_FORMAT;
+               string_list_append(&log->format, arg);
+       } else {
                return error(_("unknown group type: %s"), arg);
+       }
 
        return 0;
 }
@@ -340,6 +361,19 @@ void shortlog_init(struct shortlog *log)
        log->in2 = DEFAULT_INDENT2;
        log->trailers.strdup_strings = 1;
        log->trailers.cmp = strcasecmp;
+       log->format.strdup_strings = 1;
+}
+
+void shortlog_finish_setup(struct shortlog *log)
+{
+       if (log->groups & SHORTLOG_GROUP_AUTHOR)
+               string_list_append(&log->format,
+                                  log->email ? "%aN <%aE>" : "%aN");
+       if (log->groups & SHORTLOG_GROUP_COMMITTER)
+               string_list_append(&log->format,
+                                  log->email ? "%cN <%cE>" : "%cN");
+
+       string_list_sort(&log->trailers);
 }
 
 int cmd_shortlog(int argc, const char **argv, const char *prefix)
@@ -381,6 +415,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
                        break;
                case PARSE_OPT_HELP:
                case PARSE_OPT_ERROR:
+               case PARSE_OPT_SUBCOMMAND:
                        exit(129);
                case PARSE_OPT_COMPLETE:
                        exit(0);
@@ -406,10 +441,11 @@ parse_done:
        log.user_format = rev.commit_format == CMIT_FMT_USERFORMAT;
        log.abbrev = rev.abbrev;
        log.file = rev.diffopt.file;
+       log.date_mode = rev.date_mode;
 
        if (!log.groups)
                log.groups = SHORTLOG_GROUP_AUTHOR;
-       string_list_sort(&log.trailers);
+       shortlog_finish_setup(&log);
 
        /* assume HEAD if from a tty */
        if (!nongit && !rev.pending.nr && isatty(0))
@@ -478,4 +514,5 @@ void shortlog_output(struct shortlog *log)
        log->list.strdup_strings = 1;
        string_list_clear(&log->list, 1);
        clear_mailmap(&log->mailmap);
+       string_list_clear(&log->format, 0);
 }