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.