2

I need to revert a very old merge commit from the main branch.

The thing is, I don't want the revert operation to effect the other changes which was made from that point on on the main branch.

As far as I understand, if I use:

git revert -m 1 [hash merge commit]

It would revert to the parent commit of the merge commit and would remove all the changes which were added later.

The merge commit involves multiple files.

Is there a way to achieve this with a built in command in git other than going file by file?

1 Answer 1

2

You could rebase interactively, starting from the commit before the merge commit, and remove the commits for that merge commit.

Let's take this history from some branch feature/rebase-test:

* 1ff3147 - (tag: v0.4.3, origin/master, origin/HEAD, master) Add test to show URLs with port work * a686fbf - (tag: v0.4.2) Enable setting custom RequestHandler * f682d20 - Add php 7.4 to Travis * 0973364 - Make code coverage script CLI runnable * cb106fc - Add composer.phar to gitignore * 1d89b5e - (tag: v0.4.1) Merge pull request #62 from mvdbos/fix/event-dispatcher |\ | * 3376b9c - Revert to the legacy EventDispatcher |/ * f761a2c - Update README badges * b8447e6 - (tag: v0.4) Merge pull request #60 from mvdbos/feature/cleanup |\ | * e278cde - Simplify build and clean up use statements |/ * ac6af67 - Merge pull request #59 from mvdbos/feature/update-scrutinizer 

Now let's say I want to remove b8447e6 (and therefore e278cde, which is part of that merge commit).

I could do git rebase --rebase-merges --onto ac6af67 f761a2c feature/rebase-test). This would take everything from f761a2c forward until the tip of feature/rebase-test and rebase it onto ac6af67, which is the commit just before the merge we want to get rid of.

In my case that resulted in a few conflicts, and after solving that, my history looks like this:

* d7e5919 - (HEAD -> feature/rebase-test) Add test to show URLs with port work * 0d8e15f - Enable setting custom RequestHandler * ce365b0 - Add php 7.4 to Travis * 42d6f59 - Make code coverage script CLI runnable * ad0c861 - Add composer.phar to gitignore * 3292f4c - Merge pull request #62 from mvdbos/fix/event-dispatcher |\ | * 3e2ceef - Revert to the legacy EventDispatcher |/ * ac6af67 - Merge pull request #59 from mvdbos/feature/update-scrutinizer 

Note that the merge commit is gone and that the structure of the following commits is kept as it was, including merge commits. This is due to the --rebase-merges flag of the rebase command.

One caveat: as you may have noticed, all commits after ac6af67 have a new hash (they are really new commits). This means that the tags that existed in our previous history, don't point to those new commits. They do still exist though, so nothing will be broken. They just point to a history that still contains that merge commit you wanted to remove. Can't judge if that would be a problem for you.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I wasn't aware of that option. At the end I went with git revert. Had some conflicts but they got resolved.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.