How to recover a dropped stash in Git?
Solution 1:
Once you know the hash of the stash commit you dropped, you can apply it as a stash:
git stash apply $stash_hash
Or, you can create a separate branch for it with
git branch recovered $stash_hash
After that, you can do whatever you want with all the normal tools. When you’re done, just blow the branch away.
Finding the hash
If you have only just popped it and the terminal is still open, you will still have the hash value printed by git stash pop
on screen (thanks, Dolda).
Otherwise, you can find it using this for Linux, Unix or Git Bash for Windows:
git fsck --no-reflog | awk '/dangling commit/ {print $3}'
...or using Powershell for Windows:
git fsck --no-reflog | select-string 'dangling commit' | foreach { $_.ToString().Split(" ")[2] }
This will show you all the commits at the tips of your commit graph which are no longer referenced from any branch or tag – every lost commit, including every stash commit you’ve ever created, will be somewhere in that graph.
The easiest way to find the stash commit you want is probably to pass that list to gitk
:
gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )
...or see the answer from emragins if using Powershell for Windows.
This will launch a repository browser showing you every single commit in the repository ever, regardless of whether it is reachable or not.
You can replace gitk
there with something like git log --graph --oneline --decorate
if you prefer a nice graph on the console over a separate GUI app.
To spot stash commits, look for commit messages of this form:
WIP on somebranch: commithash Some old commit message
Note: The commit message will only be in this form (starting with "WIP on") if you did not supply a message when you did git stash
.
Solution 2:
If you didn't close the terminal, just look at the output from git stash pop
and you'll have the object ID of the dropped stash. It normally looks like this:
$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)
(Note that git stash drop
also produces the same line.)
To get that stash back, just run git branch tmp 2cae03e
, and you'll get it as a branch. To convert this to a stash, run:
git stash apply tmp
git stash
Having it as a branch also allows you to manipulate it freely; for example, to cherry-pick it or merge it.
Solution 3:
Just wanted to mention this addition to the accepted solution. It wasn't immediately obvious to me the first time I tried this method (maybe it should have been), but to apply the stash from the hash value, just use "git stash apply ":
$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219
When I was new to git, this wasn't clear to me, and I was trying different combinations of "git show", "git apply", "patch", etc.