Skip to content

How To Undo Git Commits & Changes With Reflog

Unfortunately, we’ve all been in situations where we messed up our working Git repositories. If you are really unlucky, you may have force-pushed your mess, making an even bigger mess. This is where knowing how to undo git commits or changes is useful!

Luckily for us, git reflog is here to help! This tool shows all the git operations and changes in your local repository. For this reason, even older, deleted commits will be present after a force push.

Video – Undoing In Git With Reflog

In the video below, I demonstrate how to use git reflog to undo stupid mistakes you may encounter in your software development career. For more information on the commands used, check out the rest of the post.

What Is Git Reflog?

Reflog is Git’s reference log history. Essentially, this means that git will keep the state of your local branch after everything you do on it. Even if you force push your screw ups to the remote repository!

Interestingly, each state has a hash or number associated to it. For this reason, we can use the hash (or the number) to revert our local branch back to a “good state”.

The gif below shows the output of typing git reflog on a dummy branch I’ve purposely messed up.

Using reflog to undo git commits
Figure 1: Reflog output from a git branch.

From the image above, you can see the numbers on the left, and each state operation/description on the right.

Using Git Reflog To Hard Reset Your Branch To A Good Version And Undo Git Commits!

Before we start, let’s take a look at what git reflog spits out in the terminal. The block below shows the output of git reflog once I’ve made a bad git rebase interactive to change previous git commits in my branch.

b73f3bb (HEAD -> main) HEAD@{0}: rebase -i (finish): returning to refs/heads/main
b73f3bb (HEAD -> main) HEAD@{1}: rebase -i (fixup): Very important python changes.
661c726 HEAD@{2}: rebase -i (fixup): # This is a combination of 2 commits.
d31c540 HEAD@{3}: rebase -i (start): checkout HEAD~3
8fd2501 HEAD@{4}: commit: Some changes to readme.
ff2eb6d (origin/main) HEAD@{5}: rebase -i (finish): returning to refs/heads/main
ff2eb6d (origin/main) HEAD@{6}: rebase -i (fixup): More readme changes.
57fb6b2 HEAD@{7}: rebase -i (start): checkout HEAD~3
614ee2b HEAD@{8}: reset: moving to 614ee2b
c12a248 HEAD@{9}: rebase -i (finish): returning to refs/heads/main
c12a248 HEAD@{10}: rebase -i (fixup): Very important python changes.
77d46ce HEAD@{11}: rebase -i (fixup): # This is a combination of 2 commits.
d31c540 HEAD@{12}: rebase -i (start): checkout HEAD~3
614ee2b HEAD@{13}: commit: README fixup.
57fb6b2 HEAD@{14}: commit: More readme changes.
d31c540 HEAD@{15}: commit: Very important python changes.

Basically, I’ve made a really bad rebase-interactive by fixing up my latest two commits instead of just the last one. Luckily, I can spot that the last “good version” of my branch was on the hash 8fd2501, or HEAD@{4}.

You can now either use the hash or the index to hard reset your branch, like in the following block.

# using the index
git reset --hard HEAD@{4}

# using the hash
git reset --hard 8fd2501

Both of these will achieve the same end goal: revert your local repository back to a good version! Once you’re happy after running git log, git log --name-only, or git show ... to check the status of your branch, you will need to git push -f to force push your changes (in case you’ve made changes to the tree).

How Do I Find The Correct Index / Hash To Undo Git Commits?

Essentially, there’s no other answer to this except just getting used to the reflog output, and reading them top to bottom to find your last “happy” change. For this reason, I’d recommend finding the last commit you were happy with, then using that index to reset your local branch to.

If you’re still confused about the usage, check out the video at the start of this article. You will see exactly how I use it in that example. In addition, you can also read the (slightly cumbersome) git reflog documentation.


Have I missed anything? Do you have any questions or feedback? Feel free to drop a comment below and I’ll reply as soon as possible!

Published incommand linegitterminal

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *