Recover lost Git commits


Have you ever done a git reset --hard without thinking it all the way through and found yourself having lost work that you might have been better off keeping? Well, Git actually provides an easy way to recover lost commits. Say that we have a repository with a history that looks like this.

a63d97b Added more data to newfile
b28b586 Added data to newfile
5760b1c Added newfile

Now let’s say that we do a git reset --hard 5760b1c. Our history now looks like this.

5760b1c Added newfile

To recover those two commits that we just wiped, we simply need to run the git reflog command, which gives us the following output.

5760b1c HEAD@{0}: reset: moving to 5760b1c
a63d97b HEAD@{1}: commit: Added more data to newfile
b28b586 HEAD@{2}: commit: Added data to newfile
5760b1c HEAD@{3}: commit (initial): Added newfile

Here we have a history of the actions that we’ve taken in our repository. To get those two lost commits back, we have two choices. First, we can create a new branch that starts from the latest commit that we want to recover like so.

git checkout -b recovery a63d97b

If we look at the log for the recovery branch, we see that the history is exactly the same as our original master history.

a63d97b Added more data to newfile
b28b586 Added data to newfile
5760b1c Added newfile

Our other option is to simply perform a hard reset back to our desired commit (git reset --hard a63d97b in this case). Needless to say, if you have any work in progress you’ll lose it by doing the hard reset, so you’ll want to go with option 1 if that’s the case.

One final note: the Git reflog is not kept forever. By default, entries that are more than 30 days old become eligible for deletion from the reflog (and will be deleted if you run git gc, for example), however this date can be changed at will. So if you intend on using this feature, don’t use git gc until you are satisfied with the state of your repository.