In this post I’ll show you how to do a Git uncommit, that is, if you did a git commit but have not pushed it to the repository yet, how to Git undo the last commit without loses your changes or data.

Git uncommit or git undo last commit command

Before we start, I need to point out that there isn’t an uncommit or an undo command in Git.

There is a git commit command and there are other commands to help us manage all the workflow, like git reset or git clean commands. Also the git revert command that is generally misunderstood.

Having said that, the need to uncommit in Git is real. For example, when you wrongly commit some files using conventional or semantic commit but they should be committed in their own context.

Git undo last commit

Undoing a commit is some kind of a risk thing to do if you don’t know how it works. But it’s actually really easy to do it if you do understand. Let’s see 4 different ways you can undo a git commit.

We gonna work with the following context you would have something like this, where C is your HEAD and (F) is the state of your files.

   (F)
A-B-C
  master

git reset –hard

Using git reset --hard you can undo the commit and completely remove all changes. In our scenario, the commit C would be destroyed and also throw away any uncommitted changes.

So running:

git reset --hard HEAD~

Would result in:

 (F)
A-B
master

So using git reset --hard HEAD~ now B is the HEAD. Because of the use of --hard, the files are reset to their state at commit B.

Recover git reset –hard

If you did git reset --hard but need to get that destroyed code back there’s still a way to get it. Run this command:

git reflog

The git reflog will show you a list of (partial) commit shas (that is, hashes) that you’ve moved around in. Then you can find the commit you destroyed, and run:

git checkout -b someNewBranchName shaYouDestroyed

You’ve now recovered that commit.

This can be done because commits don’t actually get destroyed in Git for some 90 days, so you can usually go back and rescue one you didn’t mean to get rid of.

git reset

Using git reset HEAD~ you can undo commit and unstage all files.

In our example, if the commit C wasn’t a completely wrong implementation, but just needed some adjustment. In this scenario probably you want to undo the commit but keep your changes for a bit of editing before you do a better commit.

So starting again with C as the HEAD commit:

   (F)
A-B-C
  master

To undo commit and unstage files, just leave off the --hard option:

git reset HEAD~1

Now the the result would be:

   (F)
A-B-C
master

When you do a git reset HEAD~1, you tell Git to move the HEAD pointer back one commit. But (unless you use –hard) you leave your files as they were. So now git status shows the changes you had checked into C. You haven’t lost any changes!

git reset –soft

Using git reset --soft HEAD~ you can undo commit and keep all files staged.

This is the lightest touch, you can even undo your commit but leave your files and your index:

git reset --soft HEAD~1

This not only leaves your files alone, it even leaves your index alone. When you do git status, you’ll see that the same files are in the index as before. In fact, right after this command, you could do git commit and you’d be redoing the same commit you just had.

Cautions

  1. Beware that this actions might not do what you expect if your erroneous commit was a (fast-forward) merge! If your head is on a merge commit (ex: merged branch feature into master), git reset --hard~1 will point the master branch to the last commit inside the feature branch. In this case the specific commit ID should be used instead of the relative command.

  2. If the commit was previously pushed to the remote repository, any undo operation will cause some problems to the rest of the users who have this commit in their local copy, when they do a git pull in the future. So, if the commit was already pushed, run this instead:

    git revert <bad-commit-sha1-id> 
    git push origin
    

Conclusions

Even without a git undo command, what would be really trick to implement and use, git offer options to back commit changes with the opportunity to redo mistakes and organize correctly your source code.