As a software engineer or developer, I am pretty sure we often use git in our work on a daily basis. Many commits are committed to your local or remote Git repository daily. However, we find some lines of codes or files in the last commit that should not be committed because of many reasons. As a consequence, we need to undo the last commit and might want to keep the last changes to be amended before re-committing them. How to do so in git? This tutorial will give you some ways to achieve this work.
Table of Contents
Undo the last commit with git reset
Using git reset with the –soft option
This is the easiest way to undo or reset the last commit by executing the git reset command with the option –soft followed by the value HEAD~1 that indicates the entry of the last commit.
git reset --soft HEAD~1
If you are not familiar with this notation, HEAD~1 means that you want to reset the HEAD (i.e. the last commit) to one commit before in the log history. Notes: the HEAD pointer of a git repo is the current location that you see when running git log --oneline
as shown in the following snippet.
af3c39a (HEAD -> master, origin/master, origin/HEAD) Assignment 4 - Task 3 be9e034 Assignment 4 - Task 2 7239be5 Assignment 4 - Task 1 575358a Fix the missing class name ce7d9d7 React Animation Components 85cbd7a React Animations 115fb34 Fetch Post Comment
In the snippet above, the last commit is the one having the message “Assignment 4 – Task 3” where we see the HEAD pointing to the branch named master. So if we undo all changes in it (i.e. the last commit), the HEAD will point to the commit hash be9e034 having the message “Assignment 4- Task 2”. Therefore, the git reset above has to use HEAD~1 as described.
Let’s play an example
Getting back to the example above, let’s see the current status:
% git status On branch master Your branch is up to date with 'origin/master'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: package-lock.json no changes added to commit (use "git add" and/or "git commit -a")
Let’s have a look at some last commits as part of the output of the command git log –oneline:
af3c39a (HEAD -> master, origin/master, origin/HEAD, dev) Assignment 4 - Task 3 be9e034 Assignment 4 - Task 2 7239be5 Assignment 4 - Task 1 575358a Fix the missing class name ce7d9d7 React Animation Components 85cbd7a React Animations 115fb34 Fetch Post Comment
Now, we want to undo the last commit meaning that the HEAD will be moved back to one commit. The HEAD should be at the commit hash be9e034 after invoking the command git reset –soft HEAD~1. Let’s see the output.
be9e034 (HEAD -> master) Assignment 4 - Task 2 7239be5 Assignment 4 - Task 1 575358a Fix the missing class name ce7d9d7 React Animation Components 85cbd7a React Animations 115fb34 Fetch Post Comment
OK. That’s exactly what we need. To make sure what the command has returned, we can check it with the command “git status”:
% git status On branch master Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: src/components/AboutComponent.js Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: package-lock.json
Using git reset with the –hard option
In contrast, the –hard option will erase the changes on files of the last commit. That’s why it is called this way as a hard reset. Be careful with this option because we cannot get back to the last updates. In other words, the last updates will definitely be lost.
Undo the last commit with git revert
The git revert command is slightly different from the git reset one because it will record a new commit with the changes introduced by reverting the last commit. In other words, the git revert command will delete the last commit in terms of undoing the last changes but won’t remove the commit from the log history.
Remember: git revert will introduce a new commit and won’t remove the last commit from the git history while the git reset won’t do those actions.
Let’s get through a demonstration
tnguyen@C02D2A6YMD6N test % git log --oneline 35a5e8b (HEAD -> main) Create b file 890026c Make the first commit
Now, we run git revert and get the result as the screenshot below.
Combining the screenshot and the git log output, we understand that git has deleted the b.txt file, added the changes to the git index, and then opened the git default editor to allow us to provide more git messages with the default messages as we see in the image. If we save and close the vim editor, we will see three commits from the log.
tnguyen@C02D2A6YMD6N test % git log --oneline 6fdd3ba (HEAD -> main) Revert "Create b file" 35a5e8b Create b file 890026c Make the first commit
Conclusion
In this tutorial, you have seen all the ways of undoing the last commit of your Git repository.
You have learned about the “git reset” command and the different ways of executing it depending on what you want to keep or not. You also learnt about the difference between the “git reset” and the “git revert” command, the latter adding a new commit in order to revert the one from your repository.
If you are curious about Git or about software engineering, we have a complete section dedicated to it on the website, so make sure to check it out!
If you like Git, you might like our other articles:
- How to create or update a commit by a specified author.
- How to create an empty commit.
- How to add some exceptions in a .gitignore file.
- How to add git branch name to terminal prompt.
- How to show files come long a specific commit.
All constructive comments are always welcomed!