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
We'll go over:
git revertdoes and how it is different from
- How to revert a single commit.
- How to revert a range of commits.
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.
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:
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:
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:
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
To revert a range of commits, simply enter the following git command in the terminal:
git revert -n <commit-hash>^..<commit-hash>
^ 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:
git status, we can see that all files added in the commits B-D have been deleted.
git revert <commit-hash>will reverse the changes made by the commit hash given, and then create a new commit.
git revert <commit-hash>will not remove the commits after the commit given, thereby preserving the commit history.
git revertwill 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
-noption prevents the auto commits, so you will need to do a manual commit.