If you are a web developer or a software engineer, it is very likely that you are pushing a lot of commits to your Git repository everyday.
However, in some cases, you committed some files that should not be pushed to your Git repository.
Sometimes, you may want to perform additional changes before issuing the commit.
As a consequence, you need to undo the last commit from your Git repository.
In this tutorial, we are going to see how you can easily undo the last commit, maybe to re-commit changes later on.
Undo Last Git Commit with reset
The easiest way to undo the last Git commit is to execute the “git reset” command with the “–soft” option that will preserve changes done to your files. You have to specify the commit to undo which is “HEAD~1” in this case.
The last commit will be removed from your Git history.
$ git reset --soft HEAD~1
If you are not familiar with this notation, “HEAD~1” means that you want to reset the HEAD (the last commit) to one commit before in the log history.
$ git log --oneline
3fad532 Last commit (HEAD)
3bnaj03 Commit before HEAD (HEAD~1)
vcn3ed5 Two commits before HEAD (HEAD~2)
So what is the impact of this command?
The “git reset” command can be seen as the opposite of the “git add” command, essentially adding files to the Git index.
When specifying the “–soft” option, Git is instructed not to modify the files in the working directory or in the index at all.
As an example, let’s say that you have added two files in your most recent commit but you want to perform some modifications on this file.
$ git log --oneline --graph
* b734307 (HEAD -> master) Added a new file named "file1"
* 90f8bb1 Second commit
* 7083e29 Initial repository commit
As a consequence, you will use “git reset” with the “–soft” option in order to undo the last commit and perform additional modifications.
$ git reset --soft HEAD~1
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: file1
$ git log --oneline --graph
* 90f8bb1 (HEAD -> master) Second commit
* 7083e29 Initial repository commit
As you can see, by undoing the last commit, the file is still in the index (changes to be committed) but the commit was removed.
Awesome, you have successfully undone the last Git commit on your repository.
Hard Reset Git commit
In the previous section, we have seen how you can easily undo the last commit by preserving the changes done to the files in the index.
In some cases, you simply want to get rid of the commit and the changes done to the files.
This is the purpose of the “–hard” option.
In order to undo the last commit and discard all changes in the working directory and index, execute the “git reset” command with the “–hard” option and specify the commit before HEAD (“HEAD~1”).
$ git reset --hard HEAD~1
Be careful when using “–hard” : changes will be removed from the working directory and from the index, you will lose all modifications.
Back to the example we have detailed before, let’s say that you have committed a new file to your Git repository named “file1”.
$ git log --oneline --graph
* b734307 (HEAD -> master) Added a new file named "file1"
* 90f8bb1 Second commit
* 7083e29 Initial repository commit
Now, let’s pretend that you want to undo the last commit and discard all modifications.
$ git reset --hard HEAD~1
HEAD is now at 90f8bb1 Second commit
Great, let’s now see the state of our Git repository.
$ git status
On branch master
Your branch is up to date with origin/master
(use "git push" to publish your local commits)
nothing to commit, working tree clean
As you can see, the file was completely removed from the Git repository (index + working directory)
Mixed reset Git commit
In order to undo the last Git commit, keep changes in the working directory but NOT in the index, you have to use the “git reset” command with the “–mixed” option. Next to this command, simply append “HEAD~1” for the last commit.
$ git reset --mixed HEAD~1
As an example, let’s say that we have added a file named “file1” in a commit that we need to undo.
$ git log --oneline --graph
* b734307 (HEAD -> master) Added a new file named "file1"
* 90f8bb1 Second commit
* 7083e29 Initial repository commit
To undo the last commit, we simply execute the “git reset” command with the “–mixed” option.
$ git reset --mixed HEAD~1
When specifying the “–mixed” option, the file will be removed from the Git index but not from the working directory.
As a consequence, the “–mixed” is a “mix” between the soft and the hard reset, hence its name.
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
Untracked files:
(use "git add <file>..." to include in what will be committed)
file1
nothing added to commit but untracked files present (use "git add" to track)
Great! You found another way to revert the last commit while preserving changes done to files.
In the next section, we are going to see another way to revert the last commit using the git revert command.
Undo Last Commit with revert
In order to revert the last Git commit, use the “git revert” and specify the commit to be reverted which is “HEAD” for the last commit of your history.
$ git revert HEAD
The “git revert” command is slightly different from the “git reset” command because it will record a new commit with the changes introducted by reverting the last commit.
Note also that with “git reset” you specified “HEAD~1” because the reset command sets a new HEAD position while reverting actually reverts the commit specified.
As a consequence, you will have to commit the changes again for the files to be reverted and for the commit to be undone.
As a consequence, let’s say that you have committed a new file to your Git repository but you want to revert this commit.
$ git log --oneline --graph
* b734307 (HEAD -> master) Added a new file named "file1"
* 90f8bb1 Second commit
* 7083e29 Initial repository commit
When executing the “git revert” command, Git will automatically open your text editor in order to commit the changes.
When you are done with the commit message, a message will be displayed with the new commit hash.
[master 2d40a2c] Revert "Added a new file named file1"
1 file changed, 1 deletion(-)
delete mode 100644 file1
Now if you were to inspect your Git history again, you would notice that a new commit was added in order to undo the last commit from your repository.
$ git log --oneline --graph
* 2d40a2c (HEAD -> master) Revert "Added a new file named file1"
* 1fa26e9 Added a new file named file1
* ee8b133 Second commit
* a3bdedf Initial commit
Conclusion
In this tutorial, you have seen all the ways of undoing the last commit of your Git repository.
You have learnt 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 :
5 comments
[…] How To Undo Last Git Commit […]
[…] amend the message of your last Git commit, you can simply execute the “git commit” command with the “–amend” […]
[…] way, you will be presented with the tag that is associated with the latest commit of your current checked out […]
Thank you. I finally feel like I totally understand the git reset command
Clear and concise. Nice Read!