2

I have a git log that looks like this:

commit 5757cbb4380322121747c78040aad08540b3c707
Author: Fabio M. Costa <email@email.com>
Date:   Tue Apr 11 11:26:29 2017 -0700

    comment 1

commit 5431794f78df3cba720bdfa8331db0c0f75a80fd
Author: Fabio M. Costa <email@email.com>
Date:   Tue Apr 11 11:23:41 2017 -0700

    comment 2

commit ad4ee4efb35e74552b4dc617d92b5ae99fdc1f3c
Author: Other Author <otherguy@email.com>
Date:   Wed Apr 12 09:07:32 2017 -0700

    ...

And I want to show the diff between all my diffs, starting from HEAD and stopping at the last one that I'm the author.

For this example, I could accomplish this manually by running git diff HEAD~2..HEAD, but I want to know how to automatically do that based on the author.

Gaston
  • 1,828
  • 2
  • 15
  • 29
fabiomcosta
  • 1,105
  • 1
  • 8
  • 10
  • 1
    Is there anything else about these commits that you know, such as "only reachable through your feature branch" or "only on your machine because you haven't pushed yet"? – Lasse V. Karlsen Apr 12 '17 at 20:59
  • I'm not at all sure what you mean by "show the diff between all my diffs". (It is possible to diff two separate `diff` outputs (this is called an *interdiff;* see http://stackoverflow.com/q/30603958/1256452 and http://stackoverflow.com/q/17792768/1256452 for instance); but we also need to know the answer to what @LasseV.Karlsen asked. Once we identify the "interesting" commits, we can look at what it means to diff any two commits. – torek Apr 12 '17 at 22:48
  • @LasseV.Karlsen interesting question, they are also generally (maybe always) the diff between my feature branch and master. Which kind of answers the question then. In this case it would be `git diff master..HEAD`. Thank you! – fabiomcosta Apr 14 '17 at 00:40

1 Answers1

0

I don't know how to do it in one line, but here's a simple bash script:

#!/usr/bin/env bash

email="$1"
upto="$(awk '{print NR-1 " " $0}' <(git log --pretty=format:'%ae' HEAD) | grep $email | head -n 1 | awk '{ print $1 }')"
from="$(awk '{print NR-1 " " $0}' <(git log --pretty=format:'%ae' HEAD~$upto) | grep -v $email | head -n 1 | awk '{ print $1 }')"
git log HEAD~$from..HEAD~$upto

Explanation

Find the first commit from the given email

First, list all the commits reachable by HEAD printing only the author's email:

git log --pretty=format:'%ae' HEAD

Then, prepend the line number, starting by 0, to each of the commits returned from the command above:

awk '{print NR-1 " " $0}' <(git log --pretty=format:'%ae' HEAD)

Then, select only the commits by the given email:

awk '{print NR-1 " " $0}' <(git log --pretty=format:'%ae' HEAD) | grep $email

Then, get the first commit by the given email:

awk '{print NR-1 " " $0}' <(git log --pretty=format:'%ae' HEAD) | grep $email | head -n 1

Then, get the line number, which represents the number of commits from HEAD:

awk '{print NR-1 " " $0}' <(git log --pretty=format:'%ae' HEAD) | grep $email | head -n 1 | awk '{ print $1 }'

Finally, store it into the $upto variable, because it's the top of the range:

upto="$(awk '{print NR-1 " " $0}' <(git log --pretty=format:'%ae' HEAD) | grep $email | head -n 1 | awk '{ print $1 }')"

Find the first commit that isn't from the given email and it's after it's first commit

The command is similar with two differences:

  • We need to find commits reachable from HEAD~$from.
  • We need to select the first commit that isn't from the given email.

So, the command, with the differences highlighted, is:

from="$(awk '{print NR-1 " " $0}' <(git log --pretty=format:'%ae' HEAD~$upto) | grep -v $email | head -n 1 | awk '{ print $1 }')"
                                                                  ^^^^^^^^^^         ^^

Printing the log

Finally, to print the log of commits from the first commit that isn't by the given email to the first commit that is from the given email:

git log HEAD~$from..HEAD~$upto

Edit: Although, as suggested in a comment, using branches and doing a git log master..HEAD is highly preferable over this solution.

Gaston
  • 1,828
  • 2
  • 15
  • 29