How To Revert Last Git Commit?
Overview
A commit in Git is the concept of taking a point-in-time snapshot of a repository, and as a developer, you may need to push many commits to your Git repository after making your code changes. However, sometimes there might arise a situation where you need to roll back some of the commits you pushed to your repository. This article describes two different ways in Git that help you to revert the changes made by the wrong commits.
Pre-requisites
Before diving into the concept of rolling back committed code from a remote repository, it's good to understand the concept of a commit in Git. A commit is one of the most commonly used concepts in Git and it is the basic step in the Git workflow. It is used to create a snapshot of the state of a repository at a given point in time. This helps you to track and view the history of your Git repository up to the point when that particular commit was made.
A commit can be identified by a unique commit ID. You can also add a message to your commit. This will show the details of the committed code changes. A commit consists of a lot of additional data, such as the author's name and the timestamp when the commit was created.
The Git push command is used to push or upload committed code changes from your local repository to a remote server. The command to push changes is:
Basically, the Git push command works by copying all code commits from your local repository from a specific branch and sending them to the remote branch on the remote server.
Introduction to Revert Last Git Commit
We know that each commit is associated with some code change pushed to the remote repository. So it's always good to commit changes only after verification, but if you make a mistake, or something doesn't go as planned, or if you want to make additional changes to the pushed commit, Git provides a nice way to roll back commits. This is also useful when tracking a bug and discovering it was introduced by a single commit. Instead of manually fixing it and creating a new snapshot/commit, you can use the Git revert command to do all this automatically.
Using the Revert Command
The revert command in Git creates another commit that reverts the changes done in the target commit. It can be used to roll back any commit by providing the commit id of the commit you want to revert.
where commit_id is a unique id associated with each commit, which gets automatically generated at the time of commit. A commit ID is an encrypted number generated using the Secure Hash Algorithm (also known as SHA). You can use the Git log command to view the history of commits for a particular repository. Let's see how we can find the commit id using the git log command:
The output of the above command will return the list of commits in the history of your git repository as shown below:
Here, this alphanumeric string in the starting represents the commit id for a particular commit.
The above Git revert command is used to revert and roll back a specific commit by its commit id. You can also use HEAD for the last commit in history to revert the last commit specifically:
The Git revert command works by creating a new commit containing the changes introduced by reverting the last commit. This is because reverting actually rolls back the specified commit. So you have to recommit your changes again to push those reverted changes to the remote repository.
Suppose you want to commit a new file to your Git repository and want to undo that commit.
When you run the Git revert command, Git automatically opens a text editor to modify and apply your changes. Here, you will find the details of the commit you are trying to revert to, and you can give your new commit message for an existing commit here, and then you can save and close a file.
Once the commit message has been processed, you will see a message containing the new commit id.
Now to check the Git history again, we can see that a new commit has been added to undo the last commit from the repository.
This action creates a new commit based on the commit specified in the revert command. This new commit is shown in the logs of Git, showing that a new commit was issued for rolling back the changes of the last commit. It shows the complete history of commits instead of pretending it never happened. The Git log will have all the history of commits. So, if you want to remove the commits from the history and do not want to show the commit created for reverting the changes, then revert is not a good choice for you, but if you want to maintain the history of committed changes, then revert is the suitable command for you instead of the reset command.
You can also edit the commit message directly and the command used to revert a specific commit while editing the commit message is:
Using the Reset Command
Git reset is another way to undo the committed changes. This command does not create another commit like the way the Git revert command does. It moves the working branch HEAD to the specified commit and discards everything after that. This command is rarely used and you should be very careful while using this command as it changes the commit history of the repository.
The command used to undo the last commit is:
The --soft option here means that you will not lose the changes that may not have been committed.
Suppose you added two files to your last commit and want to make changes to them:
As a result, you will use the Git reset command with the --soft option to roll back the last commit and make additional changes.
You can check the history using:
As you can see, after reverting the last commit, the file is still in the index (changes to the commit), but the commit has been removed from your history also. You have now successfully rolled back your last Git commit to your repository. If you want to remove all uncommitted and untracked changes along with the commits you want to revert, you can use the --hard option with the Git reset command. The command used for this is:
This will roll back not only the last commit but also the uncommitted changes.
Suppose you push a new file named "file1" to your Git repository. Now suppose you want to roll back the last commit and discard all changes.
Now let's take a look at the state of the v repository. As you can see, the file has been completely removed from the Git repository, from both the working directory and the index.
Cool, now let’s now see the state of our Git repository.
As you can see, the file was completely removed from the Git repository both the working directory and the index.
Now, if you want to undo the last Git commit and keep the changes in your working directory but not in the index, then you should use the Git reset command with the -–mixed option. As the name suggests, it is a mix of both the hard and the soft resets. The command used for mixed resetting is:
As an example, let's suppose you added a file named file1 to a commit that needs to be rolled back.
To undo the last commit, just run the Git reset command with the -–mixed option.
The –-mixed option will remove all the files from the Git index, but not from the working directory. This is a way to undo the last commit while preserving the changes made to the files
If you want to undo multiple commits, you can use the same commands as above with the commit IDs of the commits. All commits after the provided commit id will be reverted.
Here, there are three options for resetting:
- --soft option
- --mixed option
- --hard option
Reset or Revert in Git: Which is Better?
You should only use the reset command if the commit you want to reset exists locally as this command modifies the commit history and may overwrite the history that remote team members rely on. Instead, the revert command creates a new commit that reverts the changes. So if the commit you want to rollback has already been pushed to the shared repository, it's better to use revert as it won't overwrite your commit history.
For all the above reasons, Git revert should be used to undo changes on a public branch to maintain the commit history for other team members, and Git reset should be used on the private branch for undoing the changes.
Thus, Git reset is used in the local repository, and Git revert is used in the remote and shared repository. The reset command is more destructive because it modifies the existing commit histories or files, whereas the Git revert command does not manipulate any commit histories or files.
Conclusion
- A commit is one of the most commonly used concepts in Git, used to create a snapshot of the state of a repository at a given point in time.
- This helps you track and view the history of your Git repository up to the point when that particular commit was made.
- The Git push command is used to push or upload committed code changes from your local repository to a remote server.
- The revert command creates a commit that reverts changes in the target commit
- The Git revert command works by creating a new commit containing the changes introduced by reverting the last commit.
- Git reset is another way to undo the last commit. It moves the working branch HEAD to the specified commit and discards everything after that.
- The --soft option in the Git reset command means don't lose changes that may not have been committed.
- If you want to remove all uncommitted and untracked changes, you can use the --hard option to revert to the last commit.
- If you want to undo the last Git commit and keep the changes in your working directory instead of the index, you should use the Git reset command with the –mixed option.
- You should only use reset if the commit you want to reset exists only locally. This command modifies the commit history, potentially overwriting the history that remote team members rely on.
- Git revert should be used to undo changes on a public branch to maintain the commit history for other team members, and Git reset should be used on the private branch for undoing the changes.
- The Git revert command with commit id is used to revert and roll back a specific commit identified by its commit id. You can also use 'HEAD' for the last commit in history to revert the last commit specifically.
- The command git reset –soft HEAD~1 command will remove the commits but not the files and the changes will still be in the staging area.
- The git reset HEAD~1 command is the same command as the git reset –mixed HEAD~1 command and is used to uncommit and unstaged the files and save the changes to your working directory.
- The git reset –hard HEAD~1 command removes commits and changes from your working directory. This command is sometimes called a destructive command because those changes cannot be restored. So you should be careful while using this reset command with the --hard option.