Git provides two critical undo commands—git reset and revert—which may initially seem confusing, but understanding their operation is essential to creating reliable project histories. In this blog, we aim to demystify git reset and revert with examples so that you can confidently implement Git in your workflows.
Avatar

git reset

git reset is like rewinding the project's history to a particular point. Technically, the command moves the HEAD and the branch pointer to a specific commit.

A branch pointer is a reference that points to the latest commit in a particular branch's history. A commit is a snapshot of the entire repository at a point in time.

HEAD is a pointer to the most recent commit in the current branch. It is your current position within the repository. If you make a new commit, HEAD moves to point to the new commit. This means that HEAD always points to the latest changes you have made to your code.

Git reset has three modes:

  • Soft Reset (--soft): A soft reset in Git is a way to undo changes in your working directory and get back to a specific commit while keeping the changes that you have staged. This mode moves the branch pointer and the HEAD to the target commit but leaves your changes in the staging area. The staging area (also known as the index) in Git is a temporary holding area for changes that are not yet committed. When you make changes to a file, the changes are first placed in your working directory. You can then use the git add command to stage the changes for the next commit. A soft reset is often used when you want to "uncommit" your changes, but keep them in your staging area for another commit.
  • Mixed Reset (default): The default mode of git reset is a mixed reset. It moves the branch pointer and the HEAD to the target commit while clearing the staging area. This is useful when you want to uncommit and unstage your changes, but keep them in your working directory.
  • Hard Reset (--hard): This mode moves the branch pointer and the HEAD to the target commit, clears the staging area, and discards any changes in the working directory. Be cautious with this mode, as it permanently deletes uncommitted changes.

Let's say you have made a series of commits and realize that the last commit should include something other than some of the changes you have staged. You can use git reset to unstage those changes while keeping them in your working directory.

To test git reset, create a new directory:

mkdir my-git-reset-example
cd my-git-reset-example

Initialize a new Git repository and create a simple text file:

git init
echo "Line 1" > file.txt
git add file.txt

With git add, you added the file.txt to the staging area.

Create a new directory and initialize the git repository

Create a new directory and initialize the git repository

Now, commit the changes.

git commit -m "Initial commit"

The -m flag is used to specify a commit message. The commit message is a brief and descriptive note.

Now, make some changes to file.txt. Then, stage and commit them:

echo "Line 2" >> file.txt
git add file.txt
git commit -m "Add Line 2"

Run the git log command to track the commit history of the branch and understand what changes have been made.

View the commit history of the git repository with git log

View the commit history of the git repository with git log

I will now use git reset HEAD~1 to unstage the changes:

git reset HEAD~1

The HEAD is a pointer to the most recent commit in the current branch. The ~1 in the command tells Git to reset to the commit that is one before the current HEAD (the one before "Add Line 2").

The changes in the last commit are now unstaged (M file.txt), and the branch pointer has been moved back to the previous commit. "M" stands for "modified" here.

You can see that Head -> master is now pointing to the initial commit.

Reset to the commit that is one before the current HEAD using git reset

Reset to the commit that is one before the current HEAD using git reset

In this example, git reset HEAD~1 performs a mixed reset, moving the branch pointer and HEAD to the previous commit while keeping your changes in the working directory.

git revert

Git revert is a command used to create a new commit that undoes the changes introduced by a specific commit. Unlike git reset, which modifies the project history, git revert creates a new commit that effectively cancels out the changes made in the target commit. This is a safe way to undo changes without altering the commit history.

Suppose you have a Git repository with a commit history and want to undo a specific commit that introduced a change you no longer need. You can use git revert to create a new commit that undoes the changes from the target commit.

To test git revert, create a new directory:

mkdir my-git-revert-example
cd my-git-revert-example

Initialize a new Git repository and create a simple text file:

git init
echo "Line 1" > file.txt
git add file.txt
git commit -m "Initial commit"

Modify the file and create two new commits:

echo "Line 2" >> file.txt
git add file.txt
git commit -m "Add Line 2"
echo "Line 3" >> file.txt
git add file.txt
git commit -m "Add Line 3"
Edit the file and add two new commits

Edit the file and add two new commits

This time, I will use the git reflog command. git reflog is a command used to view the reference log, which records changes to the branch pointers and HEAD.

Get the history of all the changes that have been made to the HEAD pointer using git reflog

Get the history of all the changes that have been made to the HEAD pointer using git reflog

Next, I will run git revert to create a new commit that undoes the changes introduced by the target commit.

git revert HEAD~0
Undo the changes introduced by a previous commit using git revert

Undo the changes introduced by a previous commit using git revert

Git will open a text editor to enter a commit message for the new revert commit. Save and close the editor to complete the process.

This file editor will open automatically to save details about git revert

This file editor will open automatically to save details about git revert

You will see a new commit reflecting the changes made by the revert commit.

When you run git reflog again, you can see that the Head -> master location is different.

After git revert get the updated history of all the changes using git reflog

After git revert get the updated history of all the changes using git reflog

git reset vs. git revert

The git reset and git revert commands are both used to undo changes in Git. Knowing when each command should be utilized, as well as which mode is suitable for your situation, will ensure a more reliable version control history. The table below summarizes the differences between git reset and git revert.

Featuregit resetgit revert
Changes the HEAD pointerYesNo
Creates a new commitNoYes
Discards changesYes, by defaultNo
Preserves commit historyNo, by defaultYes

Use git reset when you want to discard changes that you have made in your working tree. This can be useful if you have made a mistake or if you want to start over.

Use git revert when you want to undo changes that you have committed to the repository. This can be useful if you have made a mistake in a commit or if you want to change the way that a commit was made.

Articles in seriesA Git/GitHub beginner's guide
0 Comments

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account