Recovering lost commits
August 27, 2018
So, you’ve been working on this project of yours, you are on the master branch and at some point in time, for some reason, you decided to go back to a commit. Without even realising, you make some changes and then you do
git checkout master, then you do
git status and finally you realise you’ve messed up big time.
This happened to a friend of mine recently while he was working on a big project, after we started looking for solutions, there were times when it seemed like the changes would have to be done again manually for every file. But git had us covered in a sense that git never loses anything, ofcourse unless you do
git gc, and you can almost always recover your lost stuff.
When you checkout a previous commit on a branch, say
master, you are not on any branch, instead you are in a state called
detached HEAD. This is somewhat confusing but it actually makes sense. Think of it this way, going back into history and changing something there may result in a conflict.
The commits you’ve made while in a
detached HEAD state are called dangling commits because they don’t belong to a branch. After you’ve checked out a branch and are no longer in a detached HEAD state, you may think you’ve lost the dangling commit but it is not quite right. Dangling commits can be located in many ways, two of which are:
git fsck --lost-found: It identifies all the dangling commits and writes them to the directory
stdout. It may not be the best way to identify dangling commits since it just shows the commit hash and not the commit message.
git reflog: It keeps track of all the
refs, which are references to commits, in your local directory. Hence the name
reflog. It is highly unlikely that you won’t find your lost commit here. You can sift through the output to find your lost commit and then copy it’s hash.
After copying the commit hash obtained from
git reflog, we can simply do
git merge <hash> to apply the changes to our current branch. But make sure you are on the master branch before doing this otherwise we’re back at square one.
We can easily recover a lost commit using these steps. Although there might be other cases where this may not be applicable.
git reflogto find the lost commit.
- Copy hash of the lost commit.
git merge <commit_hash>
$ git reflog # copy lost commit's hash $ git merge <hash>
You can repeat this process for a number of commits that you’ve “lost” but make sure you are on the correct branch before actually going ahead and merging the commits.