Master Git (part III). Restore undone commits.


In cases when you use git reset --hard to undo some commits, you basically erase commits. In cases you happen to change your mind about the commits you deleted, Git still provides an easy way to restore those commits with the help of reflog.

The reflog is an ordered list of commits which HEAD has ever pointed to. This is often referred to as a safety net which means that you shouldn’t worry about that your data will ever be lost even if you change git history with git reset or a wrong rebase. Git reflog allows you to almost always recover your project’s history. I say “almost” because reflog doesn’t store entries forever, but only for configured period of time.

To see a list of HEAD positions in you repository, you can run a command:

$ git reflog

If you want to restore your project’s history after changing it, all you need to do is to find required position of HEAD in reflog output and use command:

$ git reset --hard <head_position>

Suppose we made a couple of commits creating and changing a file nginx.rb

400x400

But we decided that we didn’t need this file in our project at all so we ran command:

$ git reset --hard 673a3b2 # reset to the commit before nginx.rb was introduced

All the commits made after the commit we passed as an argement would be erased from the project’s history:

400x400

If after some time we realize that we actually need this nginx.rb file in our project and the commits we just reset were not so bad after all, we can restore our commits very easily.

First, we look into reflog:

400x400 We see that at this moment (HEAD@{0}) HEAD is pointed at 673a3b2 commit to which we made a reset. And before that (HEAD@{1}) HEAD was looking at c9236fe which was the last commit that we made before we did the reset.

So we just need to tell Git to reset us again to that commit:

$ git reset --hard c9236fe # or HEAD@{1}

Our commit history is restored and the HEAD is pointing to the commit we specified:

400x400