Can git do a diff of the working copy with stash

How can I diff my current working copy against a stash?

My use case: my working copy already contains a subset of the changes in my stash@{0}, but I don't want to apply all the changes in stash@{0}. I want to do a diff to help determine which desirable changes in stash@{0} are still missing from my working copy.

25976 次浏览

If it was your most recent stash, git diff stash@{0} will do it. If not, you can use git stash list to get the index of which stash you want to compare to.

To see the difference between the actual working copy and the stash you would need to commit it first. You could then rollback the commit.

git add -A                   <- Add all the files
git commit -m "temp"         <- commit them
git diff stash@{0}..HEAD     <- diff the commit with your stash
git reset HEAD~              <- roll your commit back

If your working tree is dirty, you can compare it to a stash by first committing the dirty working tree, and then comparing it to the stash. Afterwards, you may wish to undo the commit of your working tree (to keep your history clean).

  • Commit your dirty working tree:

    git add .
    git commit -m "Dirty commit"
    
  • Diff the stash with that commit:

    git diff stash@{0}
    
  • Then, afterwards, you may revert the commit, and put it back in the working dir:

    git reset --soft HEAD~1
    git reset .
    

Now you've diffed the dirty working tree with your stash, and are back to where you were initially.

I think OP wanted the answer to see what difference the stash contains other than the files present in the working copy.

The following command shows what stash contains.

git stash show -p stash@{0}

Not sure what the OP wanted, but I use this to see what the actual diff set of the stash is:

git difftool stash@{0}^!

or

git diff stash@{0}^!

or

git diff stash@{0}^! > patchfile

You can't do this without either commiting or stashing your working copy. Stashing is probably lower-risk:

git add -A                    # Stage all changes in your working copy.
git stash save --keep-index   # Stash your working copy and leave it intact
git diff stash@{0} stash@{1}

To get rid of the stash you just made for the sake of diffing, use git stash pop or git stash drop stash@{0}.

If you want to use a commit instead, see @Magne's answer.

You can use the Unix diff command in conjunction with two Git commands just like so:

diff <(git diff) <(git stash show -p stash@{0})

Of course you can change the stash@{0} to whatever stash you want. This command is actually comparing the actual working directory (git diff) with one of your stashes.

UPDATE

You can also install colordiff and see a much much better result:

Installation:

  • Ubuntu/Debian: sudo apt-get install colordiff
  • OS X: brew install colordiff

and then just change command to :

colordiff <(git diff) <(git stash show -p stash@{0})

Yes you can use git stash show -p , check this Git diff against a stash for more information.

To do a diff of a file or folder present in the working directory with that in a stash you can do:

git diff stash@{0} -- /path/to/fileorfolder

Here stash@{0} just represents a commit HASH, so it works exactly as git diff works. stash@{0} is just a handler.

You can use git stash show -l. It shows what you want without extra stash or commit.

diff <(git diff --color) <(git stash show -p --color)
diff <(git diff --color) <(git stash show -p --color stash@{1})

Based on @petros-mitakos answer, this one about git --color option and diff's ability to show git diff's colors.