From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Subject: [PATCH 14/14] shortlog: match commit trailers with --ident
Date: Tue, 29 Dec 2015 02:38:32 -0500 [thread overview]
Message-ID: <20151229073832.GN8842@sigill.intra.peff.net> (raw)
In-Reply-To: <20151229071847.GA8726@sigill.intra.peff.net>
If a project uses commit trailers, this patch lets you use
shortlog to see who is performing each action. For example,
running:
git shortlog -ns --ident=reviewed-by
in git.git shows who has reviewed. You can even use a custom
format to see things like who has helped whom:
git shortlog --format="...helped %an (%ad)" --ident=helped-by
This does run a bit more slowly than a normal
author-grouping (about 33% slower in my tests). Some of that
is natural, because we have to spend time parsing the
trailers. But I suspect a fair bit of that could be cut off
by optimizing the trailer code, which involves quite a few
more copies of the data than we actually need.
Still, it is certainly fast enough to be usable, and
optimization can come later.
Signed-off-by: Jeff King <peff@peff.net>
---
Documentation/git-shortlog.txt | 9 +++++++++
builtin/shortlog.c | 38 +++++++++++++++++++++++++++++++++++---
shortlog.h | 4 +++-
t/t4201-shortlog.sh | 9 +++++++++
4 files changed, 56 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt
index a89a01e..16080c4 100644
--- a/Documentation/git-shortlog.txt
+++ b/Documentation/git-shortlog.txt
@@ -54,6 +54,15 @@ OPTIONS
+
- `author`, commits are grouped by author (this is the default)
- `committer`, commits are grouped by committer
+ - any other value, the `<type>` is interpreted as a case-insensitive
+ commit message trailer (see linkgit:git-interpret-trailers[1]). For
+ example, if your project uses `Reviewed-by` trailers, you might want
+ to see who has been reviewing with
+ `git shortlog -ns --ident=reviewed-by`.
++
+Note that commits that do not include the trailer will not be counted.
+Likewise, commits with multiple trailers (e.g., multiple signoffs) may
+count more than once.
-w[<width>[,<indent1>[,<indent2>]]]::
Linewrap the output by wrapping each line at `width`. The first
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 39da2d4..f774c84 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -8,6 +8,7 @@
#include "mailmap.h"
#include "shortlog.h"
#include "parse-options.h"
+#include "trailer.h"
static char const * const shortlog_usage[] = {
N_("git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"),
@@ -126,6 +127,8 @@ static void read_from_stdin(struct shortlog *log)
case SHORTLOG_IDENT_COMMITTER:
ident_header = "Commit: ";
break;
+ case SHORTLOG_IDENT_TRAILER:
+ die(_("sorry, using a trailer --ident with stdin is not supported"));
}
while (strbuf_getline(&ident, stdin, '\n') != EOF) {
@@ -149,6 +152,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
struct strbuf ident = STRBUF_INIT;
struct strbuf oneline = STRBUF_INIT;
struct pretty_print_context ctx = {0};
+ char *oneline_str;
ctx.fmt = CMIT_FMT_USERFORMAT;
ctx.abbrev = log->abbrev;
@@ -174,6 +178,12 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
return;
}
break;
+ case SHORTLOG_IDENT_TRAILER:
+ /*
+ * We might have multiple matches, so deal with it in the loop
+ * below.
+ */
+ break;
}
if (!log->summary) {
@@ -183,7 +193,26 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
format_commit_message(commit, "%s", &oneline, &ctx);
}
- insert_one_record(log, ident.buf, oneline.len ? oneline.buf : "<none>");
+ oneline_str = oneline.len ? oneline.buf : "<none>";
+ if (log->ident_type != SHORTLOG_IDENT_TRAILER)
+ insert_one_record(log, ident.buf, oneline_str);
+ else {
+ struct strbuf msg = STRBUF_INIT;
+ struct trailer_parse_context tp;
+ int i;
+
+ format_commit_message(commit, "%B", &msg, &ctx);
+ trailer_parse_init(&tp, &msg);
+ for (i = tp.start; i < tp.end; i++) {
+ const char *v = trailer_parse_match(&tp, i, log->trailer);
+ if (!v)
+ continue;
+ insert_one_record(log, v, oneline_str);
+ }
+ trailer_parse_clear(&tp);
+ strbuf_release(&msg);
+ }
+
strbuf_release(&ident);
strbuf_release(&oneline);
}
@@ -253,8 +282,11 @@ static int parse_ident_option(const struct option *opt, const char *arg, int uns
log->ident_type = SHORTLOG_IDENT_AUTHOR;
else if (!strcasecmp(arg, "committer"))
log->ident_type = SHORTLOG_IDENT_COMMITTER;
- else
- die("unknown ident type: %s", arg);
+ else {
+ log->ident_type = SHORTLOG_IDENT_TRAILER;
+ free(log->trailer);
+ log->trailer = xstrdup(arg);
+ }
return 0;
}
diff --git a/shortlog.h b/shortlog.h
index a365620..718b49d 100644
--- a/shortlog.h
+++ b/shortlog.h
@@ -16,8 +16,10 @@ struct shortlog {
enum {
SHORTLOG_IDENT_AUTHOR = 0,
- SHORTLOG_IDENT_COMMITTER
+ SHORTLOG_IDENT_COMMITTER,
+ SHORTLOG_IDENT_TRAILER,
} ident_type;
+ char *trailer;
char *common_repo_prefix;
int email;
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index 867a7ae..9c00ccb 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -207,4 +207,13 @@ test_expect_success 'shortlog --ident=committer (external)' '
test_cmp expect actual
'
+test_expect_success 'shortlog --ident=signed-off-by' '
+ git commit --allow-empty -m foo -s &&
+ cat >expect <<-\EOF &&
+ 1 C O Mitter
+ EOF
+ git shortlog -ns --ident=signed-off-by HEAD >actual &&
+ test_cmp expect actual
+'
+
test_done
--
2.7.0.rc3.367.g09631da
next prev parent reply other threads:[~2015-12-29 7:38 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-29 7:18 [PATCH 0/14] counting trailers with shortlogs Jeff King
2015-12-29 7:19 ` [PATCH 01/14] move string functions out of git-compat-util Jeff King
2015-12-29 7:20 ` [PATCH 02/14] log: refactor add_header to drop some magic numbers Jeff King
2015-12-31 6:21 ` Eric Sunshine
2016-01-01 8:42 ` Jeff King
2016-01-01 8:46 ` Jeff King
2015-12-29 7:22 ` [PATCH 03/14] strutil: add skip_prefix_icase Jeff King
2015-12-31 6:40 ` Eric Sunshine
2016-01-01 8:50 ` Jeff King
2015-12-29 7:27 ` [PATCH 04/14] shortlog: use skip_prefix_icase to parse "Author" lines Jeff King
2015-12-31 6:47 ` Eric Sunshine
2016-01-01 8:53 ` Jeff King
2015-12-29 7:28 ` [PATCH 05/14] shortlog: use strbufs to read from stdin Jeff King
2015-12-29 7:29 ` [PATCH 06/14] shortlog: replace hand-parsing of author with pretty-printer Jeff King
2016-01-04 9:43 ` Eric Sunshine
2016-01-04 10:17 ` Jeff King
2015-12-29 7:30 ` [PATCH 07/14] shortlog: optimize "--summary" mode Jeff King
2015-12-29 7:31 ` [PATCH 08/14] shortlog: optimize out useless "<none>" normalization Jeff King
2015-12-29 7:32 ` [PATCH 09/14] shortlog: optimize out useless string list Jeff King
2015-12-29 7:32 ` [PATCH 10/14] shortlog: change "author" variables to "ident" Jeff King
2015-12-29 7:35 ` [PATCH 11/14] shortlog: allow grouping by committer ident Jeff King
2016-01-04 9:44 ` Eric Sunshine
2016-01-04 10:23 ` Jeff King
2015-12-29 7:35 ` [PATCH 12/14] trailer: factor out config reading Jeff King
2015-12-29 7:36 ` [PATCH 13/14] trailer: add interface for parsing commit trailers Jeff King
2015-12-29 7:38 ` Jeff King [this message]
2015-12-29 7:50 ` [PATCH 14/14] shortlog: match commit trailers with --ident Jeff King
2016-01-04 9:44 ` Eric Sunshine
2016-01-04 10:31 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151229073832.GN8842@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).