shortlog: ignore commits with missing authors

Most of git's traversals are robust against minor breakages in commit data. For example, "git log" will still output an entry for a commit that has a broken encoding or missing author, and will not abort the whole operation. Shortlog, on the other hand, will die as soon as it sees a commit without an author, meaning that a repository with a broken commit cannot get any shortlog output at all. Let's downgrade this fatal error to a warning, and continue the operation. We simply ignore the commit and do not count it in the total (since we do not have any author under which to file it). Alternatively, we could output some kind of "<empty>" record to collect these bogus commits. It is probably not worth it, though; we have already warned to stderr, so the user is aware that such bogosities exist, and any placeholder we came up with would either be syntactically invalid, or would potentially conflict with real data. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Sep 18, 2013 at 17:14 UTC cd4f09e38341bdd17cf008ea57863e4b10ac176b
2 files changed +20 -2
builtin/shortlog.c
+4 -2
@@ -127,9 +127,11 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
127 author = buffer + 7;
128 buffer = eol;
129 }
130 - if (!author)
131 - die(_("Missing author: %s"),
130 + if (!author) {
131 + warning(_("Missing author: %s"),
132 sha1_to_hex(commit->object.sha1));
133 + return;
134 + }
135 if (log->user_format) {
136 struct pretty_print_context ctx = {0};
137 ctx.fmt = CMIT_FMT_USERFORMAT;
t/t4201-shortlog.sh
+16
@@ -172,4 +172,20 @@ test_expect_success 'shortlog encoding' '
172 git shortlog HEAD~2.. > out &&
173 test_cmp expect out'
174
175 +test_expect_success 'shortlog ignores commits with missing authors' '
176 + git commit --allow-empty -m normal &&
177 + git commit --allow-empty -m soon-to-be-broken &&
178 + git cat-file commit HEAD >commit.tmp &&
179 + sed "/^author/d" commit.tmp >broken.tmp &&
180 + commit=$(git hash-object -w -t commit --stdin <broken.tmp) &&
181 + git update-ref HEAD $commit &&
182 + cat >expect <<-\EOF &&
183 + A U Thor (1):
184 + normal
185 +
186 + EOF
187 + git shortlog HEAD~2.. >actual &&
188 + test_cmp expect actual
189 +'
190 +
191 test_done