2

suppose I have two commits that do exactly the same, but whose messages differ, how can I see this in git?

How to produce this; suppose I am on master, on any commit;

git checkout -b test
git commit --amend
// now edit the commit message
git diff master

this shows an empty output. The only way I found to see this difference in commit messages is:

git show --stat master > m
git show --stat > t
diff m t

which produces output like this (I did modify the git log output format a little):

1c1
< 65fb678 - (HEAD, test) add bcdef (Fri, 8 Jan 2016 11:23:51 +0100) <Chris Maes>
---
> 7f9c3ee - (master) add bcd (Wed, 6 Jan 2016 11:28:10 +0100) <Chris Maes>

is there any git command that allows to just see the difference in commit messages (with or without the normal git output)?

NOTE my question ressembles this question, but I was looking for a git command that would allow this.

Community
  • 1
  • 1
Chris Maes
  • 35,025
  • 12
  • 111
  • 136
  • A diff between linear commit messages only? – alex Jan 08 '16 at 10:35
  • preferably a solution for multiline message; but just for linear messages only might be a nice start – Chris Maes Jan 08 '16 at 10:36
  • Possible duplicate of [Is there a way to compare two diffs or patches?](http://stackoverflow.com/questions/8569699/is-there-a-way-to-compare-two-diffs-or-patches) – Antonio Pérez Jan 08 '16 at 10:43
  • The question ressembles, but my question is more whether there is a **git** command. available. Alternatives are welcome off course – Chris Maes Jan 08 '16 at 10:46

2 Answers2

3

This does the trick for me:

diff -w <(git rev-list --max-count=1 --format=%B SHA1) <(git rev-list --max-count=1 --format=%B SHA2)
  • -w ignores whitespace differences.
  • The <( ... ) syntax creates a temporary named pipe which makes the stdout of git show commands look and behave like a file, allowing diff to operate on the expected type of input.
  • --format=%B shows the raw message header+body of a commit message

You could replace diff -w with wdiff to have a word per word comparison.

EDIT

If you really want a git command, add this git alias to ~/.gitconfig:

[alias]
        msgdiff = "!bash -c '[ $# = 2 ] && diff -w <(git rev-list --max-count=1 --format=%B \"$1\") <(git rev-list --max-count=1 --format=%B \"$2\")' -"

Then you can do

git msgdiff SHA1 SHA2
Amedee Van Gasse
  • 7,280
  • 5
  • 55
  • 101
  • 2
    Yes, but you should prefer using `git rev-list --format=%B --max-count=1 SHAn` (plumbing) to using `git show` (porcelain). – jub0bs Jan 08 '16 at 10:47
  • @ChrisMaes It all depends where you want to use the command. In scripts, you should stick to plumbing command (as much as possible). – jub0bs Jan 08 '16 at 10:51
  • @Amadee : nice answer which does the trick, but I was hoping there was any git command that would allow this; this is patchwork :) – Chris Maes Jan 08 '16 at 10:51
  • @Jubobs: my question remains: why is rev-list better? What is the difference with git-show? – Chris Maes Jan 08 '16 at 10:52
  • 3
    @ChrisMaes `rev-list` is a "plumbing" (i.e. low-level) Git verb, whereas `show` is a "porcelain" (i.e. high-level) Git verb. The output of `git rev-list` is very unlikely to change in future versions of Git; however, the output of `git show` might. Therefore, using `rev-list` makes the approach more robust. – jub0bs Jan 08 '16 at 10:55
  • @Jubobs ok thanks, I didn't know the difference between plumbing and porcelain. – Chris Maes Jan 08 '16 at 10:57
  • @ChrisMaes and what goes into porcelain and then plumbing? Git is saying your code is... :) – alex Jan 08 '16 at 10:59
  • @jukobs I edited my answer. As a personal preference I put options that influence the data before options that influence the formatting. – Amedee Van Gasse Jan 08 '16 at 11:03
  • @Chris Maes no native git command, but you could roll your own. – Amedee Van Gasse Jan 08 '16 at 11:05
  • Feel free to accept my answer if you're satisfied with it, and give @Jubobs' comments some upvotes too. :) – Amedee Van Gasse Jan 08 '16 at 12:02
  • As I said: nice answer that does the trick (whence my upvote), but I am still looking whether there isn't any git command that would allow this... – Chris Maes Jan 08 '16 at 12:03
  • 1
    There. I just made you a git alias. Tested, works for me. The output of ```git msgdiff``` is identical to that of the answer I gave before. – Amedee Van Gasse Jan 08 '16 at 13:02
1

Starting with Git 2.19.0 (~Sep 2018), there's a command for comparing two commit ranges: git range-diff.

To compare two individual commits referred to by <rev1> and <rev2>, they need to be expressed in terms of single-commit ranges like this:

git range-diff <rev1>^! <rev2>^!

Example

echo "Some file content" > file.txt
git add file.txt
git commit -m "Add a file" -m "Just an uninteresting file." -m "It has 1 line"
git tag old
git commit --amend --edit
# ... Make some modifications to the commit message ...
git tag new

git range-diff old^! new^!

Output:

1:  c225627 ! 1:  99b9ca3 Add a file
    @@ Commit message
         
    -    It has 1 line
    +    It has 1 line and 3 words.
     
      ## file.txt (new) ##
     @@

Caveats / Limitations

  • The content of the compared commits needs to be sufficiently similar for them to be recognized by range-diff as a matching pair, rather than as a complete rewrite (i.e. removal of one commit + addition of another unrelated commit). This should be fine for the scenario described in the question ("two commits that do exactly the same, but whose messages differ").
  • Does not work with merge-commits
  • This is a porcelain command with output meant for humans. The format is subject to change in the future.
  • (rare edge case) The single-commit range syntax <rev>^! does not work for parent-less root commits
sls
  • 284
  • 1
  • 7