36

I'm trying to summarize the difference between an "old" and "new" state of the codebase.

  • I could just do "git log", but sadly the commit messages aren't always sufficient.
  • I could do "git diff", but I'd like to see some explanations to the differences I'm seeing, or at least commit hashes to save for later
  • I could do a "git diff --stat" and then "git annotate" for the files that changed, but I don't see how to ask annotate to only show changes since a particular commit.

Ideally, I'd like to get the output of "git diff" where all the "+" and "-" lines would be annotated with information about commits which last introduced these changes; ideally, in a git pretty format (e.g. hash, author and date).

How can this be achieved?

jkff
  • 17,623
  • 5
  • 53
  • 85

7 Answers7

6

You could write a small script which does something like

git blame before > before
git blame after > after
diff -u before after

:)

See man 1 git re: GIT_EXTERNAL_DIFF.

squadette
  • 8,177
  • 4
  • 28
  • 39
  • I tried to write some mock-up, but there are too many cases which need to be considered. However, it seems to me like this should be the way to go. – squadette Nov 06 '12 at 15:21
  • I found git-annotate worked better than git-blame when comparing against uncommitted changes. git-blame changed the column alignment for the uncommitted changes, so every line was a diff. YMMV. – Mr Fooz Jan 03 '18 at 20:54
  • The problem with this solution is the line numbers are included in the blame. So when you diff the two blames, the offset line numbers causes way too much to be included. The only time this wouldn't be a problem is if the only changes where CHANGED lines (no additions or deletions). I suppose you could do some other magic to remove the line numbers... – Kevin Gwynn Mar 14 '19 at 03:28
  • Even without the problems mentioned in the other comments, this would not be a very good solution, as it would not show in which commit a line was deleted - only new or changed lines would be correctly annotated. – M Kloster Nov 25 '22 at 13:02
  • Sorry, but answers like these do not add anything to the discussion. "Implement it yourself" is a possible solution to every problem. The question was: "is it already built in?". – Błażej Michalik Feb 21 '23 at 02:06
6

git-diff-blame seems relevant.

Display a diff alongside blame info like author and commit

Zitrax
  • 19,036
  • 20
  • 88
  • 110
5

Note that you can ask git blame to:

  • annotate from a certain commit See "Git blame — prior commits?": git blame -c fe25b6d^ -- src/options.cpp
  • or annotate from a certain date:
    git blame -c --since=3.weeks -- foo

Note bis: I prefer git blame -c to git annotate:

The only difference between this command and git-blame is that they use slightly different output formats, and this command exists only for backward compatibility to support existing scripts, and provide a more familiar command name for people coming from other SCM systems.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Yes, I saw this option, but it still outputs the complete files (just with lines untouched before the specified commit marked with that exact commit and not an earlier one), and I still have to do git diff --stat to know which files to annotate. – jkff Nov 06 '12 at 14:09
3

I don't think this is currently possible easily. But if you want to see context for a commit diff of file with blame information, you can do something like:

$ sha1=$(git rev-parse --short HEAD); git blame $sha1 -- filename |grep -C5 --color ^$sha1

git blame will annotate the file as usual, and grep will show five lines of context for every change introduced in that commit.

user1338062
  • 11,939
  • 3
  • 73
  • 67
2

I worked on a tool (python-based) to do exactly this... even counting for deleted lines doing something close to a reverse annotate (a reverse annotate is not exactly what is required because it will show the last revision where a line was present, it won't actually point to the revision where the line was deleted so it actually requires a little more analysis to figure out). I hope it suits your needs

https://github.com/eantoranz/difflame

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • the only question is that the output of difflame that I could not get which commit that delete the lines(it shows the delete lines but the commit id is not the one delete this line ) – butter Oct 12 '21 at 12:39
  • It should. Interesting. Is there a public-access repo whrere I could take a look? – eftshift0 Oct 12 '21 at 13:00
  • public-access example repo like https://android.googlesource.com/a/platform/system/core branch: android-12.0.0_r3. git-diff-blame cc25244b7^..cc25244b7 ; the result given is like ' - ^a21c4c1a8 ' , a21c4c1a8 is the line original commit , not the commit that delet that line(cc25244b7), I think we want to know why this line is removed more than how it was added – butter Nov 05 '21 at 03:30
  • I'm trying to figure out the real change that between AOSP releases(dup changes find with git log rev..rev),using combination of `git -C $repo_path --no-pager diff --name-only tag1..tag2` to get diff list and `git -C $repo_path blame -l -w -C tag1..tag2 -- $file_path | egrep '^[^\^]' | awk -F ' ' '{print $1}'` to get changed lines with commit id . The total removed file could find with `git -C $repo_path log --full-history --no-merges --oneline -1 --pretty='%H' -- $file_path` ,but the commit that only delete lines are not able to get – butter Nov 05 '21 at 03:39
1

I don't know if there is an easy way to get the annotated git diff results (like a "blamed diff").

You could use the --full-diff option for git log -p to get a commit message + diff.

mamapitufo
  • 4,680
  • 2
  • 25
  • 19
0

I had the same question, for a single file, and I found Visual Studio Code (vscode) helpful.

  • check out 2 branches in different directories
  • open a file in one branch
  • compare (ctrl-shift-p) with the same file in the other directory enter image description here
  • Hover over the commit info of a difference enter image description here to see extra commit info
carl verbiest
  • 1,113
  • 1
  • 15
  • 30