How git revert works

Useful tricks of git revert and how to use it effectively

The git revert command is used to ‘undo‘ the changes you have made in the past. Simple. But unlike other undo commands, git revert will introduce a new commit that has the inverted changes.

For example, consider the below git history

A - B - C - D - E

Assume, E is the bad commit and you no longer need those changes. So you have decided to undo the changes that E did. You have decided to go with the git revert.

git revert E

git revert will always take a commit hash. So you need to pass the commit you need to revert.

And after reverting E the commit history will be changed as below

A - B - C - D - E - E'

E’ is the reverted commit. E’ will contain reverted changes of E. But you can see that in the git history commit E is also present. And changes made by E is no longer present in the working directory.

This is one of the advantages of git revert. In this case, the git history is very clean and everyone reading the git history will understand that the particular commit has reverted for some reason.

How to do git revert

As mentioned earlier, git revert will take a commit hash.

git revert <commit-hash>

In the above image, you can see the commit history. See the HEAD commit (the latest commit). I have added a file ‘three.txt‘. Now let’s try to revert that commit.

I have reverted the HEAD commit in the above image. You can see that Git tried to invert the changes done by the HEAD commit and have deleted the file which was created by the HEAD commit.

Now see how git history has changed

You can see that the new commit has introduced that explains that it reverted the previous commit.

git revert -n

When you are reverting a commit sometimes you don’t need Git to do the commit for you. You may have to review the changes reverted by Git and then commit it yourself.

In the above example, you can see that I have reverted with -n option. So Git has reverted the changes but it didn’t commit the changes. It has just staged all the reverted changes. You can review those changes and commit them yourself.

Revert a series of commits

Reverting a series of commits will always come in handy.

git revert A..B

A and B are the commit hashes. The above command will revert commits from A to B. And remember A should be older than B.

Revert a merge commit

Reverting a merge commit is somewhat tricky. When there is a merge there are two branches included. The parent-B branch is merged into the parent-A branch.

So when you are reverting a merge commit you have to specify whether you need to revert changes of the parent-A branch or the parent-B branch.

A - B - C - E - F (branch A)
     \     /
      G - H - I (branch B)

In this above case, E is the merge commit. And if you run git revert E then git will throw a warning. You have to mention the parent branch number.

You can do

git revert E -m 1

This will revert all commits from the merge branch. So changes from G - H are reverted. So the git history will be like

A - B - C - E - F - E' (branch A)

E’ is the reverted merge commit.

Reverting a merge commit means you are inverting all the changes from the merge branch so that you can’t merge the branch again. You have to revert the ‘revert commit‘ if you need to merge back the branch.

In the above example, you can’t merge branch B to branch A again. Because it is been reverted in E’.

Assume after sometimes, you have made some changes to branch B and now you are fine with merging that branch. To do this, you have to revert the ‘revert commit‘.

git revert E'

The above command will revert the E’ commit. And now you can merge branch B to branch A.

Now the git history will look like

A - B - C - E - F - E' - E'' (branch A)

E’’ is the revert of E’

Reverting a pull request in Github and in Gitlab

In Github you should have probably noticed an option to revert a pull request.

If you have to revert a merged pull request you can use this option.

Assume that you have reverted the pull request (PR).

Now the tricky part. For some reason, you have to merge the branch again. You may have some updated commits in the branch too.

If you take a pull-request again with the branch you can see there are no changes to be merged. Because the inverted changes will already be present in the current branch so Git won’t show any changes to merge.

In the above image, you can see that we have merged the pull request and then reverted the merged pull request.

As mentioned earlier, now to merge the branch again you have to revert the ‘revert commit‘. There are two options to do it.

First, you can directly do it in Github itself. When you are reverting the PR, Github will create a branch that will have inverted changes and it will create a PR for those changes.

In the above image, you can see that Github has created a new branch revert-1-feature/git-revert and that PR has been merged to revert the changes.

Now you can again revert the changes from the ‘revert branch‘. Simple. So you have reverted the reverted changes :P. Github has made the task simple.

There is also another way of doing it. You can just revert the ‘revert commit‘ in the local and push it. Refer to the above commit history.

git revert -m 1 51de56e7bfe319e4ba670b2743eb135af0988fb3 

This is the same as reverting the PR. Git will just add another revert commit and then can push it.

Reverting is a very useful tool to ‘undo‘ the changes in your branch. It won’t affect history and everyone can understand what has been done.

Points to remember

  1. git revert <commit-hash> to revert a commit.

  2. git revert A..B to revert a series of commits. A should be older than B

  3. git revert -n <commit-hash> to revert a commit and stage all those changes without committing.

  4. git revert -m <parent-branch> <commit-hash> to revert a merge commit. Remember you have to mention the parent branch number as either 1 or 2

  5. Git hosting platforms like Github has an option to revert a PR itself. You can use that wisely.

That’s it for today :)

If you have any queries, feedback, or anything you can reply to this email.

If you need me to cover some specific topics in mind you can let me know. :)