To undo the most recent commit in Git, you can run the git reset HEAD~ command.
As a concrete example:
$ git commit -m "A commit you didn't want to make" $ git reset HEAD~ [Edit the files] $ git add . $ git commit -c ORIG_HEAD
The git reset HEAD~ command undoes the most recent commit but doesn’t change the state of your files. After this, make the necessary changes and use git add to re-commit. Then commit the changes. You can use the previous commit message with an editor by running git commit -c ORIG_HEAD.
Notice that this particular solution only works when you want to undo the latest commit that you haven’t pushed yet. Oftentimes, this is not the case.
This is a complete guide to undoing commits in Git. It will teach you the main scenarios of undoing commits including commits that are already pushed. You will even learn how to undo an undone commit. Moreover, you will see concrete examples of undoing commits to help understand the process.
1. Undo the Last Commit (That Has Not Been Pushed)
To undo the last commit you haven’t pushed, use git reset.
git reset HEAD~
Depending on what you’re trying to accomplish, there are three main ways to use the git reset command to undo the last commit or commits:
- git reset
- git reset –soft
- git reset –hard
Let’s take a closer look at each command.
1.1. git reset
To undo the most recent commit that you haven’t pushed run the following command:
git reset HEAD~
This removes the commit and keeps the changes in place. So when you run git status, you will see the files that changed prior to the commit.
Notice that you can undo any number of commits with the same command. To do more than one, specify the number of commits to undo after HEAD~.
For example, to undo 3 last commits:
git reset HEAD~3
1.2. git reset –soft
To undo the commit while keeping the changes staged, run:
git reset --soft HEAD~
This command undoes the previous commit and re-adds the changes (stages for a commit). A great example of using git reset –soft is when multiple consecutive commits could be just a single commit. The soft reset undoes a number of commits and stages them for a single commit.
For example, the following undoes the last 3 commits and stages them:
git reset --soft HEAD~3
1.3. git reset –hard
Sometimes, you might not only want to undo a commit but also remove the changes. To undo a commit and destroy the associated changes, you can use git reset –hard.
git reset --hard HEAD~
This action is destructive in the sense that it deletes all the changes associated with the commit. Although, there is a way to revert even this change as you’ll learn later in this guide.
Example: git reset HEAD~
Let’s take a look at a concrete example.
In this project, the latest commit adds a small piece of text to the info.txt file.
Your goal is to undo this commit.
To get rid of the latest commit that changes the info.txt file, let’s run:
git reset HEAD~
This removes the latest commit but keeps the changes in place.
Here’s what the status and log end up looking like after running the command:
The git reset HEAD~ undoes the latest commit and unstaged the changes.
As you can see in the above screenshot, running git status shows that the changes are still there. Also, logging the commits with git log, you can see that the last commit was indeed removed.
To get rid of the changes when undoing a commit, you can run git reset –hard. This undoes the most recent commit and destroys the changes at the same.
In Git, HEAD~ refers to the latest commit. It’s actually equivalent to saying HEAD~1 or HEAD^ you might see in other tutorials.
2. Undo a Commit That Has Been Pushed
Do you want to undo a commit you’ve already pushed?
If this is the case, you need to keep in mind others may already have pulled your changes with the unwanted commit.
The easiest way to undo a commit after the push is by reverting it.
git revert <commit-hash>
This creates a new commit that undoes the unwanted commit. In other words, the original commit remains in the version history and the new commit reverts it. When you run git revert, a text editor opens up. In this view, you can change the default revert commit message.
Let’s see a concrete example of reverting a commit using the git revert command.
Here’s the git log of a project where all the commits are already pushed in the remote origin.
The problem is the last commit that adds text to the info.txt file is not good and you want to get rid of it.
Because the commit is already pushed, you shouldn’t use git reset like when you’re undoing a local change. To undo a pushed commit, use git revert instead.
To undo the last commit in the above screenshot, let’s run:
git revert 6b832da82d8b93335c4ac4283d2175806fd2948a
This creates a revert commit that takes out the changes made in the previous commit.
Here’s what the git log looks like after the revert:
As you can see, the unwanted commit is still there. But now the most recent commit (which is the revert commit) takes away the changes made in the unwanted commit.
Undo Pushed Commit without a Trace
The easiest way to undo a pushed commit is by reverting it using the git revert command. After the revert, all your teammates need to do is pull the changes in.
But the issue with revert is that it leaves a trace to the version control history. Usually, this is not a problem! But if you want to undo a commit like it never happened, you need to do a reset followed by a force push. Just remember that this causes hassle with team members because you’re rewriting commit history.
To undo a pushed commit like it never happened, run:
git reset <bad-commit-sha> git push -f <remote-name> <branch-name>
As a concrete example:
git reset 6b832da82d8b93335c4ac4283d2175806fd2948a git push -f origin main
After the force push, your team members can’t just pull the changes because removing a commit changed the history of the project. Instead, they will need to do a fetch + rebase, which happens with the following command:
git pull --rebase
In other words, you might need to communicate the undo to your teammates so that they are prepared to not only pull but rebase the changes.
3. How to Undo Accidental Undo
Did you accidentally undo a commit you want back?
No worries! You can easily do this by using git reflog. The git reflog keeps track of all the updates with a technique called reference log.
Thanks to git reflog, it’s almost impossible to lose commits and changes. For example, if you did a hard reset to a commit, you can always use the git reflog hashes to revert the change.
Let me show you a concrete example.
Let’s see a concrete example where you accidentally undo a commit and get it back.
Here’s an example project where there’s a commit for adding each file to the project:
Reset vs Revert in Git
Now, let’s say you accidentally delete the last commit (Add file 3) by running git reset –hard HEAD~. As you know, this change removes the commit and the changes. In this case, it deletes the file3.txt. To undo the undo, check the git reflog and reset to the last good commit.
- Open the reference log with git reflog.
- Read through the recent partial commits and choose the last good commit.
- Reset the project to the last good partial commit by using the unique hash.
Here’s an illustration of accidentally undoing the last command and reverting it back with git reflog:
4. How to Undo Uncommitted Local Changes
Did you make changes that you want to undo and you haven’t committed them yet?
In this case, you can
- Do git status to check the files with changes.
- Run git checkout your-file-name to undo all the changes in it.
git status git checkout your-file-with-changes
Let’s see a concrete example.
Here’s an uncommitted change made to the info.txt file on an example project:
The git status command shows that the info.txt file has changed. But let’s say you don’t want to do this change.
To undo the change, you can just check out the file by running
git checkout info.txt
Now the changes are gone and the git status shows nothing to commit. This action reverts the file to the stage it was in during the previous commit.
Notice that when you do this, you’ll lose all the changes you’ve made since the previous commit!
5. How to Undo Git Add
For the sake of completeness, let’s take a look at how you can undo git add.
To undo git add, you run git reset. This unstages all the changes for all the files.
To undo add for a particular file you can call git reset <file-name>. This removes the specific file from the about-to-be-committed list without touching changes in other files.
git reset <file-name>
Today you learned how to undo git commits in common scenarios.
The most typical need for undoing a commit is to undo the most recent unpushed commit locally. To do this, you can use git reset HEAD~. This removes the commit while keeping the changes in place.
But be careful when undoing commits. If you have already pushed the commit, undoing it without proper precautions and communication with your team can cause some headaches.
Thanks for reading.