Git: Comparing Two Versions

Russell Bateman
16 July 2012
last update:

Method 1

How to compare the file between two different commits. Say your colleague just committed a file and you want to see what he did. He said he only changed the passwords for a user.

    $ git diff HEAD^..HEAD accountmgr_db.js
    diff --git a/userstuff.js b/userstuff.js
    index dea7bb9..719fd75 100755
    --- a/userstuff.js
    +++ b/userstuff.js
    @@ -147,7 +147,7 @@ var partner1 = db.accounts.find( { "email" : partner1_email } );
     db.profiles.insert(
            {
             "_id":partner1_profileoid,
    -               "password":"B4u7S/D3EX+xMexF8Vtbhw==",
    +               "password":"OrBw8zMqwpA9LJL9DPvjig8JAL8Rc17cVHrP1aF5zOS2OwQsoAv1a/pROsbfKGLQ",
                    "accountoid":partner1_oid,
    @@ -293,7 +293,7 @@ var toodles2 = "toodles-partnery";
     db.profiles.insert(
            {
             "_id":ObjectId( "000000000000000000000992" ),
    -               "password":"B4u7S/D3EX+xMexF8Vtbhw==",
    +               "password":"OrBw8zMqwpA9LJL9DPvjig8JAL8Rc17cVHrP1aF5zOS2OwQsoAv1a/pROsbfKGLQ",
                    "accountoid":toodles_oid,
    @@ -366,7 +366,7 @@ db.profiles.insert(
     db.profiles.insert(
            {
             "_id":ObjectId( "000000000000000000000993" ),
    -               "password":"B4u7S/D3EX+xMexF8Vtbhw==",
    +               "password":"OrBw8zMqwpA9LJL9DPvjig8JAL8Rc17cVHrP1aF5zOS2OwQsoAv1a/pROsbfKGLQ",
                    "accountoid":toodles_oid,

If this had happened two commits ago, or three commits ago, the command would just add successive carets:

    $ git diff HEAD^^..HEAD accountmgr_db.js
    $ git diff HEAD^^^..HEAD accountmgr_db.js

For even more distant commits, you can use the SHA1 hashes after discovering them. (Maybe I'll illustrate that another time.)

A practical example

You remember there was some special wiggle used long ago in one of your services to work around how your ReST service returned multiple entities. You remember that it involved "Generic". You don't remember which file nor when. Try this.

russ ~/acme/rest-server/src/com/acme/webplatform/ws $ git diff HEAD^^^^^^^^..HEAD *.java | grep Generic
-import javax.ws.rs.core.GenericEntity;
-        GenericEntity< List< Address > > entity = new GenericEntity< List< Address > >( addresses ) { };

Method 2

  1. Determine, on the basis of git log [--stat], the hashes of the two version to compare. Both version hashes must contain the file(s) you wish to diff.
  2. Issue this command:
    $ git diff older-hash:full-pathname newer-hash:full-pathname
    

    For example:

    master ~/acme $ git diff 3f3977f6818ebfa23a144d312551085a16694721:src/com/acme/sources/poop.java \
                             5e43be253a162ef4f090fe1d32f85b5cc7b20f7b:src/com/acme/sources/poop.java
    

Yet another scenario...

russ ~ $ git reset --soft HEAD

You've just committed (and maybe pushed) a bunch of changes, but would like to present them in review using Changes in IntelliJ, so you want them "uncommitted" in a sense. This command makes it so that those changes (that group of changes) aren't lost, but no longer pointed at by HEAD.

Perhaps you make additional changes, pursuant to suggestions by other teammates as well as discoveries of your own, and are ready to get them back. This command will reverse the first and additional changes will show up just as you'd expect.

russ ~ $ git reset ORIG_HEAD