Signup/Sign In

Git Reset

A lot of times, we will make incorrect commits or make commits to some other branches or we might need to delete a commit or any change that we had made previously. The Git Reset command is used to reset or undo changes in Git. These changes can be made to the HEAD, the working directory, or the staging area. Let's try and understand how Git Reset works.

Reset Changes

  • Often times we will find ourselves in situations where we have to undo certain changes. Git Reset command helps us in doing that.
  • As we know, changes can be made to the Working Directory, the Staging Area, or to the Repository. Git Reset has three options for reverting changes in each of these stages.
  • We can think of Reset as the reverse process of normal Git Workflow in which we move from the Working Directory to the Staging Area and finally commit changes to the repository.
  • A thing to note here is that we may lose reference to some commit points when resetting as the branch reference pointer is also changed along with the head. Consider the following example in which after a reset is performed to revert back to commit B, the commit point C is no longer referenced by any pointer.

Losing reference to a commit point because of reset.

Git Reset Modes

Git Reset has three modes in which it can work. Each mode will revert changes in one of the three stages of the workflow(Working Directory, Staging Area, and Repository) and will have the functionalities of the previous option. Let's take a look at these three options.

Git Reset --soft

The --soft option is used to reset changes only in the Repository. It works by changing the position of our HEAD to point to the previous commits. However, it keeps the staging area and the working directory as it is.

Git Reset --mixed

The --mixed option has the functionality of the --soft with the additional feature of resetting changes in the staging area. In this mode, Git will first revert changes in the repository by making the HEAD point to one of the previous commits and then also update the Staging Area to the state it was in when that previous commit was used. This is also the default mode that Git Reset uses.

Git Reset --hard

The --hard option is the most powerful one among the three in the sense that it has the functionalities of the above options along with an additional feature. The --hard option will also reset the changes in the working directory after resetting the Repository and the Staging Area. But one must be careful while using this option as all our unsaved changes in the working directory will be lost.

Visualizing the working of Git Reset in three modes

Git Reset Command

We learned about the three options of the Git Reset command. To reset to a previous commit we can use the commit hash of that commit.

$ git reset <option> <commit-hash>

We can also enter the position of the commit relative to our current HEAD. In the following command, Git will reset to the n-th commit before head.

$ git reset <option> HEAD~n

Working with Git Reset

Let's try to understand the three modes of Git Reset with the help of an example.

Consider we have a repository with a file called f1.txt which has the text "First Line" and these changes are committed.

Creating a file and staging and committing it.

Next, we add a line to this file and stage and commit this change.

Adding the modified file to staging area

Committing the modified file

Now, let's add another line to the file and only stage that change. Add one more line and but don't stage that change.

Only staging a change and not committing it.Adding another line to just modify the working directory.

Time to compare the three Git Reset options. First, let's look at the state of our repository.

We have one staged file, one unstaged file and two commits

When we run git reset --soft HEAD~1, it will make the HEAD point to the commit just before our HEAD but will keep the staging area and working directory intact.

Executing the Git Reset command with the --soft option

After resetting, head points to a previous commit but the staging area and working directory are as it is.

Now if we run git reset --mixed, the staged changes to the file will be lost but the working directory still has the changes. This is evident from as we can still see the unstaged file when we run Git Status.

Using --mixed option resets the changes in the staging area.

Lastly, if we run git reset --hard, even the working directory is restored to the initial version corresponding to the initial commit. We can that the contents of the file are the same as they were after the initial commit.

--hard option resets working directory as well.

Summary

We would often find ourselves in a situation where we need to go back and undo our changes. The benefit of version control systems is that we can do this if we have committed those changes previously. Git Reset is the command that helps us reset the state of the repository. This command has three options - soft, mixed and hard and they can be used according to the needs of the developer. We must be careful while using the --hard option as all unsaved changes(working directory) are also reverted to match the previous commits. Another thing to be aware of is that we might lose reference to certain commit points while resetting. Overall it is a very valuable command but should be used thoughtfully.