1811

How can I see the changes un-stashing will make to the current working tree? I would like to know what changes will be made before applying them!

SQB
  • 3,926
  • 2
  • 28
  • 49
Tegra Detra
  • 24,551
  • 17
  • 53
  • 78
  • 15
    possible duplicate of [Is it possible to preview stash application in git?](http://stackoverflow.com/questions/3573623/is-it-possible-to-preview-stash-application-in-git) – quazgar Apr 17 '15 at 13:48
  • 1
    Related post [here](https://stackoverflow.com/q/10725729/465053). – RBT Sep 25 '17 at 06:00

15 Answers15

2499

See the most recent stash:

git stash show -p

See an arbitrary stash:

git stash show -p stash@{1}

From the git stash manpages:

By default, the command shows the diffstat, but it will accept any format known to git diff (e.g., git stash show -p stash@{1} to view the second most recent stash in patch form).

thedayturns
  • 9,723
  • 5
  • 33
  • 41
Amber
  • 507,862
  • 82
  • 626
  • 550
  • 82
    `stash@{0}` is the default; you only need an argument if you want to look at previous stashes. – Cascabel Oct 06 '11 at 17:01
  • 59
    Right. I merely supplied it so that it was clear how to look at other stashes besides `{0}`. – Amber Oct 06 '11 at 17:16
  • 106
    This won't show the diff between the stash and the current working dir, but between the stash and it's original parent. Right? From the manpage: "Show the changes recorded in the stash as a diff between the stashed state and its original parent." – Magne Jan 21 '13 at 12:31
  • 1
    @Magne correct - but it will still show what the OP requested (what changes will be made when applying it) in a general sense. – Amber Jan 21 '13 at 17:19
  • 17
    @Amber - True, although if your current working tree is dirty, it matters, and makes it a bit more complicated. I came at it from that angle, and found an procedure I shared in my answer below. – Magne Jan 23 '13 at 10:05
  • 1
    Is there a short form for `stash@{XYZ}`? – TankorSmash Jun 12 '13 at 20:10
  • 2
    @TankorSmash That is the short form. – Amber Jun 13 '13 at 02:23
  • 1
    @Amber Fair enough. Suppose you can't get much shorter without sacrificing readability. – TankorSmash Jun 13 '13 at 02:33
  • 2
    note: if you use fish shell, you need to escape the {} with \ as in git stash show -p stash@\{0\} – Marco Aurelio Oct 25 '14 at 08:35
  • 20
    what does the `-p` stand for? – Gerald Apr 10 '16 at 14:07
  • 13
    @Gerald "patch" i.e. show the diff, not just the commit details. – Amber Apr 11 '16 at 05:55
  • @Amber is it possible to see the diff for only one file in the selected stash? – gen Jul 21 '17 at 15:03
  • 2
    @TankorSmash: a shorter form that worked for me: git stash show -p 1 (will show the second stash, along with a diff) – AtliB Dec 05 '17 at 13:12
  • 5
    `git stash show -p 1` for showing diff between `stash@{1}` and `current`. So it's more concise like this. – jpmottin Jan 08 '19 at 09:38
  • 3
    I wish they had called it ```git stash diff```. – Pete Alvin Feb 05 '20 at 16:01
  • 2
    The more correct answer is `git diff HEAD stash@{0}`, though applying the stash to the current working tree may fail, therefore it is not possible to show the changes but only the diff. – jolvi Aug 29 '20 at 10:05
  • @gen you can use the above command mentioned by jolvi and add the filename at the end – Rstar37 Aug 09 '21 at 20:58
  • Why does the git documentation say 'This option is only valid for `push` and `save` commands.'? It seems to work for the `show` command just fine. Is this an error in the documentation? – Jespertheend Mar 03 '23 at 22:08
418

To see the most recent stash:

git stash show -p

To see an arbitrary stash:

git stash show -p stash@{1}

Also, I use git diff to compare the stash with any branch.

You can use:

git diff stash@{0} master

To see all changes compared to branch master.


Or You can use:

git diff --name-only stash@{0} master

To easy find only changed file names.

Community
  • 1
  • 1
czerasz
  • 13,682
  • 9
  • 53
  • 63
  • 14
    This does not answer the specific question. If you created the stash from master (to save work for later), then do some commits for other work on master, then do `git diff stash@{0} master`, you get a diff of your stash against the current master (which includes the work done on master after the stash was made), not the files/lines that the stash would change, which is what the question is about. – Tom De Leu Aug 01 '12 at 14:40
  • 66
    I'm glad you answered the question even if it wasn't an answer to the exact question. It gave more information, and I think it's great to know how to get a diff between a branch and whatever other branch you wan to compare it to. I also liked learning the --name-only flag :) – Rebekah Waterbury Aug 03 '12 at 18:04
  • 9
    this also allows looking at the differences using a custom diff viewer, e.g. `git difftool --tool=... stash@{0} HEAD` – Andre Holzner Oct 19 '12 at 14:22
  • 12
    @TomDeLeu Good observation and an important point. To compare a stash item with its parent, this seems to work: `git diff stash@{0}^ stash@{0}` – erikprice Jan 18 '13 at 19:09
  • 2
    As well, you can add the filename `git diff stash@{0} master -- filename` to get the changes to a specific file. – David Aug 10 '16 at 15:28
  • For me it is necessary to always escape the braces `stash@\{0\}`, will the tab completion does this automatically for `git stash` commands, it does not do it for `git diff`. It might be worth mentioning it, as it can be confusing if you copy commands and get an error. – DerWeh Feb 22 '18 at 09:24
  • @DerWeh That depends on your shell (and possibly that shell's configuration). Seems like I don't need backslashes in my ZSH setup (though I don't know if there's some configuration for it, as I've simply installed a bunch of plugins and got to working). – trusktr Dec 10 '18 at 22:55
  • I use `--name-status` over `--name-only` so I can see what change was made to the file; A: add - D: delete - M: modify .... – Rockin4Life33 Aug 28 '19 at 15:18
134

If the branch that your stashed changes are based on has changed in the meantime, this command may be useful:

git diff stash@{0}^!

This compares the stash against the commit it is based on.

theintz
  • 1,946
  • 1
  • 13
  • 21
  • so good I added an alias to `~/.gitconfig` : `laststash = diff stash@{0}^!` – sbeam Mar 17 '14 at 12:12
  • 10
    Perfect pair: `git difftool stash^!` for diff of last stash against commit it was based on, `git difftool stash HEAD` for diff of last stash against current commit (stash@{n} for earlier stashes) – ChrisV Jun 15 '14 at 18:13
  • 22
    For those who were like me and have never seen the ^! before: [commit^! is a range specifier which means: this commit, but none of its parents.](http://stackoverflow.com/q/25651269/1248889) – jgawrych Feb 03 '15 at 16:56
  • "git diff stash@{0}^!" boils down to "git diff stash@{0} ^stash@{0}~1 ^stash@{0}~2 ......." but as git diff takes only 2 commits, it shows the diff between stash@{0} and ^stash@{0}~1 and looks the ^ at the beginning of 2nd commit doesn't make any different and git ignores it. – Naga Kiran Oct 20 '15 at 14:05
  • I prefer this version to be able to use my preferred diff tool (Beyond Compare of course!). This also shows the change in this stash which I believe is the original question, as opposed to an alternative mentioned in the above comments "git diff stash@{X}^ stash@{X}" which shows more than just the stashed diff. – user107172 Aug 23 '17 at 01:49
  • 1
    What shell are you in? Mine requires me to quote it: `git diff 'stash@{0}^!'` – trusktr Dec 10 '18 at 23:01
  • This is good; but what I actually want is to see *what would change* through that pop merge. This is actually not different from any other merge preview, see e.g. https://stackoverflow.com/questions/5817579/how-can-i-preview-a-merge-in-git, and open to the same solutions (apply to an ad-hoc branch etc.). So what I want to see is neither the changes preserved in the stash (the diff stash@{0}^!) (because some of those may also be present in the HEAD) nor is it, more obviously, the simple diff stash@{0} HEAD. – Peter - Reinstate Monica Apr 25 '19 at 10:00
  • This seems to show the diff in the wrong order (shows additions as removals, and removals as additions). – trusktr Jul 25 '19 at 05:34
  • @trusktr This works in zsh and bash, but fish requires you to either quote stash@{0}^! as you have done, or escape the curly brackets e.g. stash@\{0\}^! – johnny Jan 22 '20 at 07:01
79

Depending on what you want to compare the stash with (local working tree / parent commit / head commit), there are actually several commands available, amongst which the good old git diff, and the more specific git stash show:

Compare stash with ↓ git diff git stash show
Local working tree git diff stash@{0} git stash show -l
Parent commit git diff stash@{0}^ stash@{0} git stash show -p
HEAD commit git diff stash@{0} HEAD /

While git stash show looks more user friendly on first sight, git diff is actually more powerful in that it allows specifying filenames for a more focused diff. I've personally set up aliases for all of these commands in my zsh git plugin.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
David Deprost
  • 4,072
  • 1
  • 20
  • 27
  • 3
    This is the only correct answer (as of at least git 2.17.1) This is the only answer having "git stash show -l" as well as a bit more information. Thank you very much for posting it - how do we get it upvoted to the top? Put a comment on the topmost one? – Starman Jun 16 '20 at 23:11
  • 2
    I get `error: switch `l' requires a value` when running `git stash show -l` – mmmm Mar 11 '22 at 22:12
  • 2
    `-l` is no longer a valid option in newer versions of git. – Matthew Thomas Sep 20 '22 at 01:46
  • 1
    Depending on your shell (e.g. PowerShell) you may need to put the arguments with curly brackets inside of quotes (e.g. `git diff "stash@{0}"`) – Matthew Thomas Sep 20 '22 at 01:51
55

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 undo the commit with the dirty working tree (since you might not want to have that dirty commit in your commit log).

You can also use the following approach to compare two stashes with each other (in which case you just pop one of the stashes at first).

  • Commit your dirty working tree:

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

    git diff HEAD 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.

Max Wallace
  • 3,609
  • 31
  • 42
Magne
  • 16,401
  • 10
  • 68
  • 88
  • Is there a way to do this but to only see a diff of the files that would be changed by what is in the stash? – lagweezle Oct 04 '16 at 19:14
  • 1
    In **2020** this is much simpler; check out my [up-to-date answer](https://stackoverflow.com/a/62118546/6033410). – David Deprost May 31 '20 at 15:37
  • 1
    Interesting, I didn't know about `git stash show -l `. Does it diff the latest stash against the working (dirty) copy? How do you use it without getting `error: switch l requires a value`? – Magne Jun 01 '20 at 06:14
  • Yes indeed, it diffs against the (possibly dirty) working copy. You use it simply by entering `git stash show -l`. As to why it doesn't work for you, I can only guess you might be on an older version of git? I'm on git v2.20.1, and it works flawlessly without errors. – David Deprost Jun 01 '20 at 12:39
36

@Magne's answer is the only one to (very late) date that answers the most flexible/useful interpretation of the question, but its a fair bit more complicated than necessary. Rather than committing and resetting, just stash your working copy, compare, then unstash.

git stash save "temp"
git diff stash@{0} stash@{1}
git stash pop

That shows you the differences between the top of the stash stack and your working folder by temporarily making your working folder changes become the top of the stash stack (stash@{0}), moving the original top down one (stash@{1}) then comparing using the original top in the 'new set' position so you see the changes that would result from applying it on top of your current work.

"But what if I don't have any current work?" Then you are in the normal boring case. Just use @Amber's answer

git stash show

or @czerasz's answer

git diff stash@{0}

or admit that stashing and unstashing is fast and easy anyway, just unstash the changes and inspect them. If you don't want them at the moment throw them (the current index/working folder changes) away. In full that's

git stash apply
git diff
git reset
git checkout
mleonard
  • 559
  • 5
  • 12
SensorSmith
  • 1,129
  • 1
  • 12
  • 25
  • 3
    This simple approach (stash and then compare to another stash) is safe and easy to understand. For some use cases you may wish to also stash untracked files with `git stash save -u` – mleonard Nov 22 '18 at 12:32
26

Just in case, to compare a file in the working tree and in the stash, use the below command

git diff stash@{0} -- fileName (with path)
nilobarp
  • 3,806
  • 2
  • 29
  • 37
Pramod B R
  • 612
  • 6
  • 7
20

This works for me on git version 1.8.5.2:

git diff stash HEAD
Rimian
  • 36,864
  • 16
  • 117
  • 117
  • 2
    Misleading! The question is: How can I see the changes un-stashing will make to the current working tree? This shows the diff between the stash and the HEAD which may be VERY different than what will be applied with `git stash apply`. – MikeJansen Feb 11 '16 at 14:10
  • Please read on the question more "I would like to know what changes will be made before applying them!". I am providing a fast answer to this. – yerlilbilgin Feb 12 '16 at 08:37
  • Also you can see all the other answers are somehow about diff'ing the current head (or working set) against the stash. Why is only my answer misleading? That is not fair. – yerlilbilgin Feb 12 '16 at 08:39
  • @yerlilbilgin See my response on your answer below. – MikeJansen Feb 23 '16 at 14:51
  • We can ommit HEAD, it's by default, isn't it? – Al.G. Oct 09 '16 at 12:37
10

If you have tools for diff (like beyond compare)

git difftool stash HEAD
yerlilbilgin
  • 3,041
  • 2
  • 26
  • 21
  • 1
    Misleading! The question is: How can I see the changes un-stashing will make to the current working tree? This shows the diff between the stash and the HEAD which may be VERY different than what will be applied with `git stash apply`. – MikeJansen Feb 11 '16 at 14:10
  • 1
    If you think this is misleading, please check all the other answers. That is not fair! – yerlilbilgin Feb 23 '16 at 07:28
  • 1
    You'll note that I copied that same comment to the other answer which was just as misleading (pretty much the same answer). Other answers that already had a similar comment I left alone. If you understand how git stash works, then you will realize that diff'ing the stash against HEAD is not what gets applied (which is what the OP asks). The actual "stash" is the diff between the stash commit and what was before it. This patch is then applied to the HEAD. So if you want to know what the OP asked, you must show the diff between the stash and the commit before it, which the correct answers do. – MikeJansen Feb 23 '16 at 14:50
  • 1
    This answers the question more directly than any of the other (needlessly) long answers, and does exactly what the OP asked, short of removing `HEAD`. I could modify @yerlilbilgin's answer to remove HEAD but I think anyone who uses git can figure that part out and me lengthening the answer would make it less readable. No blame on @yerlibilgin. – Sridhar Sarnobat Jan 05 '18 at 22:45
10

I believe git diff <current-branchname>..stash@{0} is the most intuitive way to compare the changes between the local working tree and the most recent stash. Replace stash@{0} with the applicable stash number as needed.

Beware that git diff stash@{0} may produce misleading results. If the two histories of your stash and current branch have diverged, the diff will look like you’re adding all the new stuff in your stash and removing everything unique to the current branch.

answer based on the git book

Also, note that double dot .. and triple dot ... specify different commit comparisons, and I am referring to the double dot for this answer. See the git book for details

ciiyan
  • 101
  • 1
  • 4
6

One way to do this without moving anything is to take advantage of the fact that patch can read git diff's (unified diffs basically)

git stash show -p | patch -p1 --verbose --dry-run

This will show you a step-by-step preview of what patch would ordinarily do. The added benefit to this is that patch won't prevent itself from writing the patch to the working tree either, if for some reason you just really need git to shut up about commiting-before-modifying, go ahead and remove --dry-run and follow the verbose instructions.

xenithorb
  • 161
  • 1
  • 3
5

She the list of stash

git stash list 
stash@{0}: WIP on feature/blabla: 830335224fa Name Commit
stash@{1}: WIP on feature/blabla2: 830335224fa Name Commit 2

So get the stash number and do:

You can do:

 git stash show -p stash@{1}

But if you want a diff (this is different to show the stash, that's why I write this answer. Diff consider the current code in your branch and show just show what you will apply)

You can use:

git diff stash@{0}

or

git diff stash@{0} <branch name>

Another interesting thing to do is:

git stash apply
git stash apply stash@{10}

This applies the stash without removing it from the list, you can git checkout . to remove those change or if you are happy git stash drop stash@{10} to remove a stash from the list.

From here I never recommend to use git stash pop and use a combination of git stash apply and git stash drop If you apply a stash in the wrong branch... well sometimes is difficult to recover your code.

Raúl Martín
  • 4,471
  • 3
  • 23
  • 42
3

Combining what I learned in this thread and in this one, when I want to see "what is inside the stash", I first run:

git stash show stash@{0}

That will show what files were modified. Then, to get a nice visual diff in a difftool, I do:

git difftool --dir-diff stash@{0} stash@{0}^

This will display all the differences at once of the given stash against its parent.

You can configure the diff tool in ~/.gitconfig, e.g. with Meld:

...
[diff]
    tool = meld
Community
  • 1
  • 1
Ferrard
  • 2,260
  • 3
  • 22
  • 26
2

I found that none of the answers here gave me quite what I needed for my use case:

Made some changes, stashed them, wanted to check what had changed without applying the stash.

The best I found for a diff between the working tree and the stash was:

git diff stash@{0}

or simply:

git diff stash

But this showed the diff the wrong way round for how I expected it: Lines added (usually in green) were shown as removed (usually red), and vice versa.

Reversing the diff got me what I needed:

git diff stash -R

At this point you get identical results running this command after stashing as you would running git diff before the stash.

1

FWIW This may be a bit redundant to all the other answers and is very similar to the accepted answer which is spot on; but maybe it will help someone out.

git stash show --help will give you all you should need; including stash show info.

show [<stash>]

Show the changes recorded in the stash as a diff between the stashed state and its original parent. When no is given, shows the latest one. By default, the command shows the diffstat, but it will accept any format known to git diff (e.g., git stash show -p stash@{1} to view the second most recent stash in patch form). You can use stash.showStat and/or stash.showPatch config variables to change the default behavior.

Rockin4Life33
  • 2,240
  • 1
  • 31
  • 29