loading...
Cover image for Git and GitHub: Git Revert

Git and GitHub: Git Revert

lofiandcode profile image Joseph Trettevik ・4 min read

Song of the Week

Introduction

Last week we covered how to do a hard reset of your repository. Though they're sometimes necessary, hard resets are a pretty destructive method of rewinding your repository because they alter the commit history.

Today's post will cover the nondestructive rewind, aka git revert.
We'll go over:

  • What git revert does and how it is different from git reset.
  • How to revert a single commit.
  • How to revert a range of commits.

Git Revert vs Git Reset

The git revert <commit-hash> command will reverse the changes made by the commit hash given, and then create a new commit. This is the preferred method for undoing the changes of a specific commit if that commit has already been push to a shared remote repository because it preserves the commit history.

This is different from a git reset, because a reset will move the HEAD ref to the commit hash given, and drop all the commits after that one. A git revert only reverses the commit that was given and keeps all the following commits and the changes that were made in them. This makes git revert great for removing a bug that was introduced by a single commit without having to redo all the work in the following commits.

How to Revert a Single Commit

To revert a single commit, enter the following git command in the terminal:

git revert <commit-hash>

You can also pass git revert a reference to the commit that is relative the HEAD ref. So, if you entered git revert HEAD~2, the changes from the third most recent commit would be reversed.

Let's look at an example. I created a local repository with some files whose names match the commit in which they were created, which looks like this:
Alt Text
All these files just have the text "added content" in them and each was added with their own commit. The git log looks like this:
Alt Text
Now let's say there was some bug in commit A that we wanted to undo but keep commits B-D. We would enter the following git command:
Alt Text
You can see in the git log that the git revert command automatically created a commit. Also, I used HEAD~3 to reference commit A. Remember that most recent commit is equal to HEAD, which can be written as HEAD~0. So, the fourth most recent commit is HEAD~3.

Now if we look at the working directory you'll see that the "commit-A" has been removed, but the rest remain.
Alt Text

How to Revert a Range of Commits

To revert a range of commits, simply enter the following git command in the terminal:

git revert -n <commit-hash>^..<commit-hash>

Notice the ^ before the two periods. That caret symbol tells git to include that first commit hash given in the range. And the -n option tells git to not create a commit, but to instead stage the changes in the Staging Index and the Working Directory. This way you can do one commit manually to maintain a neat commit history.

In the same example we used above, lets say we want to rewind to commit A and maintain the commit history. You could do that like this:
Alt Text
By running git status, we can see that all files added in the commits B-D have been deleted.

Now we just need to commit those changes.
Alt Text
In the git log we see that commits B-D are still in the commit history even though their changes have been reversed.

If we open the Working Directory, we'll see that it has indeed rewound back to commit A.
Alt Text

Takeaways

  • git revert <commit-hash> will reverse the changes made by the commit hash given, and then create a new commit.
  • Unlike git reset, git revert <commit-hash> will not remove the commits after the commit given, thereby preserving the commit history.
  • git revert will also accept a commit reference based on HEAD, like git reset HEAD~3, for example.
  • git revert -n <commit-hash>^..<commit-hash> will reverse the changes by the range of commits given(inclusively), and will stash the changes in the Staging Index. The -n option prevents the auto commits, so you will need to do a manual commit.

References

Cover Image - Mt St Helens
Git Revert - atlassian.com
Git Revert - Git Docs
How to revert multiple git commits? - stackoverflow.com

Discussion

pic
Editor guide