Barbaric Tip of the Week: How to Recover a Lost Commit With Git

| Comments

Barbaric Tip of the Week is a weekly series whose main purpose is to share tiny bits of knowledge that I find specially useful and interesting.

Last week I experienced one of the weirdest moments I have ever had with git and something that should never ever happen within the secure confines of a version control system: I lost a commit. My source code, everything that I had been working on for 3 hours wiped out from existence.

Has this ever happened to you? Would you like to know how you can recover a lost commit?

It was a sunny afternoon of summer, a warm and gentle breeze was blowing, the birds were happily chirping and I was about to push my beautifully crafted code to the remote repo. Just another great day in the life of a programmer (wink).

I did a git pull --rebase as I had done 2 million times before and I got some conflicts, no biggie, these things happen. I fixed the conflicts, continued the rebase and done! I dutifully verified that my commit was just as I wanted before pushing and…

…wait…

…where… is… my… code?? WHERE IS MY COOOOODE!?!? ^%#$^[email protected]@#

The logs only showed a commit which only contained the changes done in the resolve conflicts stage of the rebase but none of the code that I had been working on for the past 3 hours. Holy shit! How can this happen? Isn’t the whole purpose of a version control system to prevent code from disappearing?

Well, when there’s will, there’s a way as they say. I stopped moping, remembered that git stores everything that you do in the .git folder and tried to find a way to recover my information. As it turns out, git has a great command that you can use in these cases: git reflog.

Git reflog gives you access to a sort of history of what your HEAD has been in the past and therefore let’s you recover from fatal actions like losing a commit. In my particular case, a git reflog showed me a state similar to this:

1
2
3
4
5
6
P> git reflog
448258e HEAD@{0}: rebase finished: returning to refs/heads/master
448258e HEAD@{1}: pull --rebase: continued updating linq chapter
7e455f5 HEAD@{2}: checkout: moving from master to 7e455f570e5a1c20f7d6593cb9ff9c758d7e4e94^0
fa079fa HEAD@{3}: commit: continued updating linq chapter
86dca63 HEAD@{4}: commit: Continued improving linq chapter

Where I could see the SHA of my beloved lost commit previous to the rebase and allowed me to recover it following these steps:

1
2
3
4
# Create a new branch at the commit I wanted to recover
P> git branch recover-commit fa079fa
# Merge that branch with my current branch
P> git merge recover-commit

Pheeeew… You cannot imagine how relieved and happy I was to recover my work. And you! Whenever you experience anything like that or miss some source code, check out git reflog. It’s worth the time.

Would you like to learn more about git reflog and data recovery in git? Then take a look at:

Have a great week ahead!

Comments