64

There are many SO questions that show how to view the output of a git diff command in a diff viewer like meld using git difftool or otherwise. I am not asking about git diff though.

I want to see the output of git show <previous commit sha1> in a diff viewer like meld. How can I do this?

Buttons840
  • 9,239
  • 15
  • 58
  • 85

6 Answers6

70

You can use git difftool to show a single commit.

Say you want to see the commit with the sha1 abc123:

git difftool abc123~1 abc123

(~1 tells git to move to the previous commit, so abc123~1 is the commit before abc123)

If you use this regularly, you could make a custom git command to make it easier:

  1. Create a file called git-showtool somewhere on your $PATH with the following contents:

    git difftool $1~1 $1
    
  2. Give that file execute permissions:

    chmod +x ~/path/to/git-showtool
    
  3. Use the command git showtool <sha1 or tag or ...>

  4. Profit.
georgebrock
  • 28,393
  • 13
  • 77
  • 72
  • also, you should cross-check what commit you are going to view and whether it contains many changed files. because meld is going to open one after the other consecutively – user2291758 May 19 '15 at 14:16
  • Unfortunately I get the following error. Launch 'p4mergetool' [Y/n]? Y /mingw64/libexec/git-core/git-mergetool--lib: eval: line 124: unexpected EOF while looking for matching `"' /mingw64/libexec/git-core/git-mergetool--lib: eval: line 125: syntax error: unexpected end of file – jpierson Mar 06 '17 at 16:19
  • 2
    `git show $commit` is not equivalent to `git difftool $commit~1 $commit` if we are reviewing a merge commit. git show presents the merge commit in a special format as produced by `git diff-tree --cc $commit`. See https://git-scm.com/docs/git-show – Abdul Rauf Jul 18 '18 at 05:52
  • 1
    You can use the `^` to do parent commits also like `git difftool abc123^ abc123`. Apply multiple times to go up the tree higher like `abc123^^^` – jocull Aug 03 '18 at 14:57
  • Somebody should merge this nice and simple tool to mainline git – ericcurtin Oct 22 '20 at 12:50
30

Building on georgebrock's response, you can create an alias in .gitconfig, something like this:

showtool = "!showci () { rev=${1:-HEAD}; git difftool $rev~1 $rev; }; showci $1"

Then you can run it with git showtool abc123 (without needing to create a separate shell script for this). If you leave out the revision it will default to HEAD.

sagittarian
  • 991
  • 1
  • 10
  • 14
14

Translating sagittarian's suggestion for the less git savvy, add this to your global .gitconfig file which resides in C:\Users[user name] if you are a windows user:

[alias]
    showtool = "!showci () { rev=${1:-HEAD}; git difftool $rev~1 $rev; }; showci $1"

or you can execute the following command in the get bash shell:

git config --global alias.showtool '!showci () { rev=${1:-HEAD}; git difftool $rev~1 $rev; }; showci $1'

which will make the change to the .gitconfig file for you.

Michael Szczepaniak
  • 1,970
  • 26
  • 35
5

Building on sagitarrian's answer, here's a small change for more generic rev syntax:

showtool = "!showci () { rev=$(git rev-parse \"${*:-HEAD}\"); git difftool $rev~1 $rev; }; showci"

I use rev-parse to transparently allow complex rev expressions.

I removed the $1 at the end, since the alias is called followed by the arguments; it passes unnoticed when using only $1 but breaks $* behaviour.

This allows doing nice things like:

git showtool :/some nasty bug
John Gliksberg
  • 122
  • 2
  • 6
  • 1
    Equivalent shell command: `git config --global alias.showtool '!showci () { rev=$(git rev-parse "${*:-HEAD}"); git difftool $rev~1 $rev; }; showci'` (I wasn't able to suggest the edit) – David Cook Mar 03 '21 at 01:06
2

Geogrebrock answer is fine, but can be improved thus:

commit=$1
shift
git difftool $commit~1 $commit $@

Put it in executable (chmod +x) file somewhere in $PATH.

Now you can pass additional arguments, for example specify what files you want to see (and ignore others):

$ git showtool 6a40ec6ffb9338b0548aefab92fded1bffb1648a -- src-cmn/
MateuszL
  • 2,751
  • 25
  • 38
1

The git-showcommit file (executable) in the PATH should be as follow:

#!/bin/bash

git difftool --dir-diff $1^..$1

then you can simply call the new tool by git showcommit HEAD or git showcommit a5b26d5

fiorentinoing
  • 948
  • 12
  • 20