RSS Feed Subscribe to RSS Feed

 

Git revert a merged branch

The article discusses how to revert changes that have already been pushed to your remote git branch, particularly reverting the changes that come from a branch merge.

Note that the git log formats below are obtained using the “Pretty git log in one line” approach such as this.

git reset vs git revert

git reset is useful for rolling back changes when you have not yet pushed. git revert is what is needed however if you have already pushed and need to roll back.

git revert

For example, if you have this commit log:

* 858d292 –  added c.txt (1 minute ago)

* 81f1e60 –  added b.txt (2 minutes ago)

* abdeeb6 –  added a.txt (3 minutes ago)

And you do:

git revert 858d292

You will end up with the state prior to your last commit (so, for example, only a.txt and b.txt now exist), and a commit history that looks something like this:

* 1fdfa2c –  Revert “added c.txt” (1 minute ago)

* 858d292 –  added c.txt (2 minutes ago)

* 81f1e60 –  added b.txt (3 minutes ago)

* abdeeb6 –  added a.txt (4 minutes ago)

The git revert actually adds a new commit that reverts the commit in question.

git revert for merge commits

How does git revert work when you have a merge?

For example, you merge a feature branch, called fb, into your main branch, push, and then regret it (e.g. it introduced a bug, or you didn’t mean to merge that branch).

git revert in Github

If the merge was a result of a Pull Request, the Github UI provides the easiest mechanism to revert:

 

Clicking the Revert button will open a new pull request, with a message

“Revert <you previous commit message>”

For example, “Revert “added file: fb1.txt””

git revert from command line

However, what if you didn’t use GitHub to merge? For example, you merged directly on the command line? If you have a git commit history like this…

* 858d292 – Merge pull request #3 from sabram/fb (1 minutes ago)
|\
| * 77fee79 – (origin/fb, fb) added file: c.txt (2 minutes ago)
|/

* 81f1e60 –  added b.txt (3 minutes ago)

* abdeeb6 –  added a.txt (4 minutes ago)

…you can still roll back the merge using the “git revert” command.

 

git revert “mergecommit” won’t work

If you simply do

git revert 858d292

You will get an error:

error: commit 858d292 is a merge but no -m option was given.
fatal: revert failed

This is because a merge commit has (at least) 2 parents and git doesn’t know which of the two parents you are trying to revert back to. In this example, the 2 parents are 77fee79 and 81f1e60.

git revert mainline

Instead, we tell the git revert command which parent we want to revert to using the -m option (short for mainline).

-m1 says uses the first parent (in our case 81f1e60. -m 2 says the branch parent (in our case 77fee79.

So for example, doing

git revert 858d292 -m1

will leave you with this commit log

* 6db9c3c – (HEAD -> master) Revert “Merge pull request #3 from sabram/fb” (3 seconds ago)
* 858d292 – Merge pull request #3 from sabram/fb (1 minutes ago)
|\
| * 77fee79 – (origin/fb, fb) added file: c.txt (2 minutes ago)
|/

* 81f1e60 –  added b.txt (3 minutes ago)

* abdeeb6 –  added a.txt (4 minutes ago)

Where you will basically be in the same state as before the feature branch was created. This is essentially what the GitHub UI revert did.

Note that in this scenario, you could also have done:

git revert 858d292 -m2

Which is basically saying revert back to the state of the feature branch (and in this example, would have no effect).

Tags: , , , ,

Leave a Reply