I accidentally executed git stash pop
twice getting me one stash behind of where I wanted to be. How do I undo the last pop? I do want the first pop but not the second one so reset --hard HEAD
won't do it for me.
We can use the reset command with some options to git undo failed stash pop. The git reset has recently learned the --merge option. The --merge option is like the default --mixed option, but it only applies to the files affected by the merge operation.
If you made two stashes, then just call git stash pop twice. As opposed to git stash apply , pop applies and removes the latest stash. You can also reference a specific stash, e.g. Save this answer.
"Undoing" git stash pop
is kind of painful unless you have the raw commit-IDs for your stashes listed somewhere (e.g., on your screen).
The git stash
documentation has directions (at the end) for recovering dropped stashes. These are the instructions you want, as pop
is simply "apply
and then drop
". That means if you recover both stashes, you can then use git reset --hard
to restore everything, git stash pop
(or—safer since it won't "drop"—git stash apply
) the one stash you wanted to use, and then verify everything.
If you can find and restore both stashes, that's probably how I'd do it.
If you can find just the second stash (the one you want to "un-apply"), you can attempt to reverse-apply it.
Here's the "incantation" from the documentation:
git fsck --unreachable | grep commit | cut -d\ -f3 | xargs git log --merges --no-walk --grep=WIP
When you run this you'll get a list of commits that represent each w
commit of each "stash bag". Let's say it dumps out something like this:
Checking object directories: 100% (256/256), done.
Checking objects: 100% (66/66), done.
commit 2783bc8cf98192acc3de647d6cbff2c1a2aecca5
Merge: 222c4dd 8466342
Author: ...
Date: Wed Feb 12 17:38:13 2014 -0700
WIP on branch: 222c4dd add clobber-reg example
commit e9fc3cc8e7864813b54bb1281c845297a16b1b47
Merge: 222c4dd d790e1f
Author: ...
Date: Wed Feb 12 17:28:00 2014 -0700
WIP on branch: 222c4dd add clobber-reg example
The date
line is useful here as it's the time the stash was made. It's pretty hard to tell those two stashes apart, isn't it? Save the raw SHA-1 IDs somewhere, and run git stash show -p
on each one. When you find a valuable one, give it a name:
$ git tag recover-exp-1 e9fc3cc8e7864813b54bb1281c845297a16b1b47
$ git tag recover-exp-2 ...
Once you're sure which ones are the right recovered ones, you're good to go in terms of doing things like git reset --hard
and then git stash apply
. You can now apply by the tag names made above:
$ git reset --hard # ouch, all gone now (maybe "git stash save" first)
$ git stash apply recover-exp-3 # that turned out to be the right one
When all is saved and committed the way you want it, you can delete the various "recover" tags. (Note, you can use any name you like; there's nothing special about recover-exp-
, that's just something I made up here.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With