Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accidentally ran git stash pop twice

Tags:

git

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.

like image 968
amphibient Avatar asked Feb 18 '14 04:02

amphibient


People also ask

Can I undo a git stash pop?

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.

Can I git stash pop twice?

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.


1 Answers

"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.)

like image 62
torek Avatar answered Oct 27 '22 00:10

torek