Explore Courses Blog Tutorials Interview Questions
0 votes
in DevOps and Agile by (19.4k points)

I frequently use git stash and git stash pop to save and restore changes in my working tree. Yesterday I had some changes in my working tree that I had stashed and popped, and then I made more changes to my working tree. I'd like to go back and review yesterday's stashed changes, but git stash pop appears to remove all references to the associated commit.

I know that if I use git stash then .git/refs/stash contains the reference of the commit used to create the stash. And .git/logs/refs/stash contains the whole stash. But those references are gone after git stash pop. I know that the commit is still in my repository somewhere, but I don't know what it was.

Is there an easy way to recover yesterday's stash commit reference?

Note that this isn't critical for me today because I have daily backups and can go back to yesterday's working tree to get my changes. I'm asking because there must be an easier way!

1 Answer

0 votes
by (27.5k points)

If you know the hash of the stash commit you dropped, then you can easily apply it as a stash:

git stash apply $stash_hash

You can also create a separate branch for it with

git branch recovered $stash_hash

You can do whatever you want with all the normal tools. When you’re done, just blow the branch away.

Let us talk about finding the hash:

Case 1: If you have only just popped it and your terminal is still open that means you will still have the hash value printed by git stash pop on screen.

Case 2: Otherwise, you can find it by using the following methods: 

Linux, Unix or Git Bash command:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

Powershell command:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}

This will display your all the commits at the tips of your commit graph which are no longer referenced from any branch or tag – every lost commit, including all stash commits you’ve ever created will be somewhere in that graph.

Again, 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}' )

Now in order to spot stash commits, look for commit messages of this form:

WIP on somebranch: commithash Some old commit message

Remember: 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.

Related questions

+6 votes
2 answers
+1 vote
1 answer
+9 votes
2 answers

Browse Categories