There will be different scenarios when you require undoing a commit in Git. Depending on the type, and level of criticalness you may use different options/commands for reverting back the commit in Git.
In this tutorial, you will find different ways of undoing the previous commit.
Method 1: Using the reset command with hard and soft options
By definition, the reset command of Git is used to set the current HEAD to the specified state. So, you may use the reset command to revert the last commit or back to the specified state. For example:
git reset --hard HEAD~1
Keeping the changes in the previous commit example
Basically, the reset command has three forms of invocation. The one is used in the above command i.e. –hard. The other two are:
- — mixed
- –soft
So, for example, you do not want to discard changes made: files added, or any other changes. For that, you may use the –soft in reset command as used below:
If you run this command after the above command:
You will see, the changes in the last commit are preserved, however, the HEAD pointer is moved back to the previous position.
Still unclear, let us go through adding files in a branch, committing the changes and then doing hard and soft operations for undoing changes in the example below.
An example of undoing commit in Git
To understand the undo process by using Git restart with –hard and –soft flags, let us start with the basics.
For the demo, I have created a remote and local repository. The remote repository is created on GitHub and locally on a Windows system.
By right-clicking on the local system folder, I opened Git Bash (as explained in this tutorial).
Fast forward, I ran a few commands as shown in the graphic below – for synchronizing the remote branch with the local, creating a new branch locally, and started adding files:
(For initializing the empty git repository locally)
For synchronizing the remote repo with local.
(downloading any content in the remote repository to the local)
Creating the first local branch where we will commit three times and undo the committing to level 1 and 3 later.
This command is executed so we may add files in this branch.
After creating tst1.txt file in the local folder, execute the add command for adding a file in demo1 branch:
Performing the first commit:
The above graphic shows all these commands and output messages on Git Bash.
Pushing these changes to the remote repository:
If you refresh you remote repo, it should display the locally created branch and a text file with the commit message.
To learn how to undo commits in Git, I have created two more text files (tst2.txt and tst3.txt) on the local repo and executed the commit commands as follows:
Commit2 with a message:
Adding file 3:
Commit number 3 command:
You can see three files are listed as a result of running $ ls command after making this commit for the demo1 branch.
The files are: tst1.txt, tst2.txt, tst3.txt
Running the reset command for undoing the last commit
Finally, we have reached to the point where I will execute the reset command.
The first test is running the reset command with –hard flag. See how it outputs:
$ git reset --hard HEAD~1
This is followed by running this command:
The output of these two commands:
There you go, the “HEAD is now at c177186 Added text file – Commit 2” i.e. to our second commit; so we have undone the last commit.
Running the $ls command also shows only two files now. If you go to the local repo folder, you will see the tst3.txt file is also removed.
This is because of the –hard flag with the reset command. So, you have to be careful when reverting back to the last commits.
You may lose your important files if undone carelessly. I will show what happens if we use –soft flag.
Reverting to first commit rather than last commit example
If you want to go back to the first or any other commit rather than the last commit, you may provide a desired number with the HEAD i.e.
Instead of HEAD~1, use the HEAD~2 or HEAD~3 etc.
For the example, I am again adding the third file (tst3.txt), making the commit again and then execute with the HEAD~3 option as follows:
This is followed by:
And finally execute the reset command:
The result is:
YES, you can see the $ ls command is listing only the README.md file – no text files that we committed by first, second and third commits.
Again, if you go to the local repo folder, it should only have the README.md file – all text files should have been removed.
Using the –soft flag for undoing last commit example
Now let us go through using the –soft flag in the reset command for undoing the last commit. For that, I am again adding three files and performing the commits one by one for each change as in the above section.
After that, we have three files in our demo1 branch in the local repository. The three files are also visible in the local repo folder.
Running the reset with –soft
Before running the reset command, I executed the status command as follows:
This is followed by reset with –soft:
This command tells Git to move the pointer to the one step back without removing the changes– i.e. our second commit (before that, it was on commit 3).
I again ran the status command. See what are the output of all the commands on Git Bash:
You can see, that the second status command shows a new file: tst3.txt as compared to the first command. Also, as I checked the local repo folder, it shows all files (tst1.txt, tst2.txt, tst3.txt) unlike the reset with –hard flag that showed only two files (tst3.txt was removed).
Conclusion
Based on the above experiment, we may conclude that if you require to undo the last commit when you are sure to discard everything associated with that commit, then use the reset command with –hard flag.
If you require keeping the changes (like holding the code files or any other changes) then use the reset with –soft flag.
We also saw that not only you may undo the last commit by reset command but may go to any level of commits i.e. earlier commits as well by specifying the number in HEAD~.
Method 2: Undo the last commit message example
As with every commit, a message is also saved. This is quite likely that spelling mistakes may occur as well as the message may be incomplete or more information is required to be added than the last commits’ message.
In the case when you only require changing the message in the last commit, you should not use the reset command to go through all process again.
Instead, you may use the easier option – commit with –amend flag.
Demonstration
- In the following example, I have added a text file in the local branch.
- This is followed by using the commit command with a message.
- I also used the push command with –force flag for submitting the changes in the remote repository.
- In the message, I “accidentally” made typos and wanted to fix the message. This is how the message is fixed.
Add command:
Running the commit with the wrong message:
There, I wanted to use the word Commit rather Comic. However, I also ran the push command and the changes were “live” on Github:
Fixing the message:
Now running the commit command again with –amend flag:
Again executed the push command to fix the message in the online repo as well:
The result in the online repo:
You can see, the amendments are made in the online repository without using the reset command.
Method 3: Use the revert command to undo the commit
Another way of undoing the commit (last or any) is using the revert command. In this way, you have to provide the commit ID in the revert command.
The following commands show reverting the last commit and any other specified commit by revert command.
For the example, I have added another file (tst4.txt) file in our above-created branch and ran the commit command as shown below:
The arrow shows the commit ID as we execute the commit command.
Now execute the revert command with that code, for example:
It will take you to another terminal asking you to enter the message. After entering a message, press the following keys (one by one):
And press Enter.
The output of the test during this test is:
You can see, the $ ls commands show four files before running the revert command. After that, it shows only three files, thus the commit of the tst4.txt file is undone.
This should return a full long SHA-1 that you may use in the revert command. Similarly, this command returns the shortcode of HEAD:
Or, simply use the following command:
That should return handy information about the commits. Get the code there for the required commit that you want to revert.