Rescue a missing git stash
I lost a git stash the other day mysteriously. Here is the process I used to recover a lost stash.
Where is my Stash?
Lets assume you have a git stash:
$ git stash Saved working directory and index state WIP on master: 1f96501 Unmark two old posts as drafts, check spelling HEAD is now at 1f96501 Unmark two old posts as drafts, check spelling $ git stash list stash@{0}: WIP on master: 1f96501 Unmark two old posts as drafts, check spelling
And you accidentally drop it:
$ git stash drop Dropped refs/stash@{0} (7e765965bfdeb34647773af3b7b2cc0c1629843c)
Or you pop the stash and then lose it somehow...
$ git stash pop On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: content/2016/09/05-finding-files-without-newlines.rst no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (7e765965bfdeb34647773af3b7b2cc0c1629843c)
Recovery
Your stash doesn't show up in the stash list:
$ git stash list
Stashes aren't in the normal reflog output:
$ git reflog 0e47d62 HEAD@{0}: commit: Add newlines to the ends of posts 1f96501 HEAD@{1}: commit (amend): Unmark two old posts as drafts, check spelling 79df53a HEAD@{2}: commit: Unmark two old posts as drafts, check spelling
You might be able to see your stash in:
$ git reflog --all 0924cfe refs/stash@{0}: WIP on pipeline: 6ffcf23 Update packages 6ffcf23 refs/heads/master@{0}: pull origin master: Fast-forward
However if its not there, git provides access to them as a "dangling commit":
$ git fsck --no-reflog | awk '/dangling commit/ {print $3}' Checking object directories: 100% (256/256), done. Checking objects: 100% (724/724), done. bb99ae9cde077bd807774d314760786742537df8 b2932a09d1e9a00349e1e9d968de5aace8bb65cd 7754cdc89aae40896419508e0f2c9bcb1112a9e5 32bdea0498f633c613491add06cf1fd606fe80bd 93dd0ecabc594a37047960665a4f4025ca577970 7e765965bfdeb34647773af3b7b2cc0c1629843c 91f681ad3cfc1ca29b441d20c547e24f3d38e42f 79df53ac5f83477694f48ad1a6db2fcc9b3a3a90
Once you have a list of the dangling commits, you can view them individually by using their git sha.
$ git show -p 79df53ac5f83477694f48ad1a6db2fcc9b3a3a90
Or use shell expansion to combine the two previous steps in case you have a lot of dangling commits.
$ git show $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )
Read through the changesets to find your missing stash.
Rescue
Finally, now that you have found the missing stash you can use the apply subcommand to recover it:
$ git stash apply 7e765965bfdeb34647773af3b7b2cc0c1629843c On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: content/2016/09/05-finding-files-without-newlines.rst no changes added to commit (use "git add" and/or "git commit -a")