Barbaric Tip of The Week: How to Recover A Lost Commit With Git
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!?!? ^%#$^$@@#
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:
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:
# 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!
Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.