Sometimes you end up stashing code, then at some point those stashes get cleaned. And one day, you may encounter the situation I faced this week:
Fine, this code is merged, so let’s delete the related stashes. Done! And… hey… wasn’t this part of the feature supposed to be in the codebase? Is the stash I just deleted lost forever?
Here’s the two-steps recovery procedure.
Let’s run this command for a project where all stashes were trashed:
git fsck --unreachable | grep commit | cut -d ' ' -f3 | xargs git log --merges --no-walk
Let’s use the commit hash of the second stash:
git update-ref refs/stash 4b3fc45c94caadcc87d783064624585c194f4be8 -m "My recover stash"
And that’s it! You’ll find your stash as usual, using
git stash list or by having a look in your favorite Git client.
Always use a commit message using
git stash save -m "My commit message": without message, the only informations helping to identify a stash are its timestamp and the branch it was saved from, which may not be enough compared to a strong explicit name.
Commit messages also help Git clients:
- GitUp, the Git client I use, completely fails at showing unnamed stashes. That’s probably why you can’t create a stash in GitUp without giving it a name, which is great!
- The well-known SourceTree succeeds at showing unnamed stashes, but as you can guess, the list isn’t friendly to browse:
git stash pop,
git stash apply does not remove the stash from the list of stashes, which can avoid some loss.
Finally, I’d recommend to avoid
git stash. Instead, try to use a branch. This seems obvious but it only comes to me as I was finding a way to recover a stash: maybe I should use temporary branches instead of stashes. Using the Git Flow method at work, this could have come to my mind before encountering a painful experience.
If you have any stash hint or experience that you want to share, comments are welcome.