This is a scary story, not like a horror movie, but frightening enough to give any developer the shivers. The story goes a little something like this…

A customer directs your attention to a bug you know you’ve solved, tested and shipped. You fixed it one day ago so the bug can’t be there, the customer must be wrong?!

After running the application, waiting to not see the bug, it’s there again! You quickly head to your source code and… yikes, your old code is there, with no traces of your fixes. You compare it against other versions and can’t find a git change associated with your name. Was it a merge conflict or uncommitted? Could it have been the Matrix conspiring against you or even gremlins?

Then suddenly you recall deleting an unimportant git stash this morning because everything has been deployed already.

For those who are not git-savvy, git is a controlled version system and a stash, is a temporary shelf to place your unfinished drafts. If you’re in the middle of working on something and need to test your code as it was before you started, you can place your changes in a stash, return to a stable starting point to test and when you’re ready, re-apply the stash and resume working.

I realized at this point I had placed the fixes I needed in a stash, which I had later deleted. I didn’t panic, as I could have re-written the fix, but as a developer, I prefer to learn how to reverse the deletion, even if it took 10 hours of trial-and-error instead of a 10-minute rewrite. And we consider ourselves clever people.

Recovering the Stash

I started off my research at the source of all developer knowledge A.K.A. StackOverflow where I discovered this question Retrieve deleted stash in Git using SourceTree an exact depiction of my problem. Reading through the answers, I discovered that a stash is just another commit in your repo and that deleted ones are orphaned. If you can remember the description assigned to your stash, you’re more or less fine. We have a nice release log, so I easily found the bug reference number which the lost code fixed. I always include the bug reference number in stash descriptions, so I was ready to retrieve the stash from the command line:

$ git fsck 2> /dev/null | awk '/commit/{print $3}' | git show --stdin --grep '2230'

Woah that’s quite a line, let’s break it down:

1. The funny 2> /dev/null part ignores all error messages (they are thrown to /dev/null a dark hole in every UNIX system).

2. git fsck checks your repo for orphaned commits.

3. This prints a list of information, containing the id of the commit and it’s type, for example:

dangling commit 6108663eaaac4b7e850f6d492cf83e7b65db2c97
dangling commit b526a825c7730075eb5938917c8b8b7a98f63cdf
dangling commit 04479ae959fc7470d04e1743f1c7149414c366fa
dangling blob c6609e5099056da80ea1cdf5bea302225bd6b7ed
dangling commit 9d65fa867f23d28ce618fcb5d7988180efb67f9c

4. We’re after commit ids, which is the third part of each line, so we run: awk '/commit/{print $3}’ to obtain the third part of each line.

5. git show shows information about that particular commit. So if we filter and print those containing the bug number… voilà!

commit 85a1e41e6e34f9b15eac6202228ff64b83a4b0db
Merge: 9861f11 6b11160
Author: Diego Freniche Brito
Date: Fri Jul 22 12:51:00 2016 +0200
On develop: issue2230
commit 706391d60512961599107d8ddf13bb450814fff4
Merge: d02ea68 15d0729
Author: Diego Freniche Brito
Date: Wed Jul 27 10:45:24 2016 +0200
On feature/issue_2230: issue2230

And I finally found my stash, which I re-applied by running:

git stash apply 706391d60512961599107d8ddf13bb450814fff4

Phew, I’m saved! Kudos to git, StackOverflow and Terminal for saving my bacon once again.

Have you been in such scary territories like this? Share your thoughts with us!

Jose Luis Franconetti

Jose Luis is a senior software engineer, with a strong experience in mobile, backend and dev-ops.