On Thu, Sep 07, 2017 at 12:30:01PM -0700, Stefan Beller wrote:
> > "--follow" switch is not listed on
> > https://git-scm.com/docs/git-shortlog so maybe it's not supported. In
> > this case I would expect error message.
> >
> > Tried the following versions:
> > "git version 2.14.1.windows.1" on Windows 7
> > "git version 2.7.4" on Ubuntu 16.04
>
> The shortlog takes most (all?) options that git-log
> does, e.g. in git.git:
That's definitely the intent, but I think --follow is just buggy here.
We don't seem to trigger a diff, which is where "git log" does the
follow check (because of the way it's bolted onto the diff, and not the
actual pathspec-pruning mechanism).
Something like the patch below seems to work, but there are a lot of
open questions. And it would probably want to do something to prevent
nonsense like "shortlog -p" from showing actual diffs.
I suspect a better solution might involve actually building on
log-tree.c to do the traversal (since this internal traversal is
supposed to be equivalent to "git log | git shortlog").
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 43c4799ea9..31274a92f5 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -175,8 +175,31 @@ static void get_from_rev(struct rev_info *rev, struct
shortlog *log)
if (prepare_revision_walk(rev))
die(_("revision walk setup failed"));
- while ((commit = get_revision(rev)) != NULL)
- shortlog_add_commit(log, commit);
+ while ((commit = get_revision(rev)) != NULL) {
+ int show_commit;
+
+ /* trigger a diff to give --follow a chance to kick in */
+ if (!commit->parents) {
+ /* should diff against empty tree or respect --root? */
+ show_commit = 1;
+ } else if (commit->parents->next) {
+ /* how to handle merge commits? */
+ show_commit = 1;
+ } else {
+ struct commit *parent = commit->parents->item;
+
+ parse_commit_or_die(parent);
+ parse_commit_or_die(commit);
+ diff_tree_oid(&parent->tree->object.oid,
+ &commit->tree->object.oid,
+ "", &rev->diffopt);
+ show_commit = !diff_queue_is_empty();
+ diff_flush(&rev->diffopt);
+ }
+
+ if (show_commit)
+ shortlog_add_commit(log, commit);
+ }
}
static int parse_uint(char const **arg, int comma, int defval)