2

Threre are multiple resources that will tell you how to revert a branch merge in git in case you figured out a bug in the branch. The steps following such a merge will either be reset/correct errors in branch/merge if the branch wasn't pushed upstream, or revert/correct errors in branch/revert the revert/merge. However, this only relates to the situation when there was an error in the branched code. Today I tried to revert a merge that was invalid because of the way conflicts were solved in the merging commit.

The situation before:

master o -- 1 -- C
        \      /
branch   a -- b

The developer that merged the branch into master encountered commits related to the code implemented by someone else in commit 1. He resolved the conflicts and committed them, thus creating a merging commit "c". The problem was that he introduced a bug while doing that. What I wanted to do then was to revert this merge and re-merge it properly, creating something that looks like this:

master o -- 1 -- C -- ~C -- C1
        \      /          /
branch   a -- b ----------

Where "~C" is the reverted "C" and "C1" a correct merge. Unfortunately it looks like I can't do this.

Of course resetting to 1 and re-merging "branch" into "master" works, but the changes were already upstream and I didn't want to do any dirty tricks.

Solutions I found in thread Undo a Git merge that hasn't been pushed yet didn't take me anywhere.

The cleanest idea I got was to just fix the code broken in "C" and commit them to "master" but in this case you get no help from git, such as a list of conflicting files or highlighted conflicting lines, which in this case was very helpful.

Any ideas?

Community
  • 1
  • 1
mikosz
  • 393
  • 1
  • 8
  • Why didn't ~C -> C1 work? Did it say nothing had changed because b was already merged to C? Did you try to cherry pick the changes from branch into master after you committed ~C? – Andrew T Finnell Nov 02 '12 at 16:04
  • As you guessed - ~C -> C1 didn't work because the merge was already done. As it was said in the question I linked to (and the article linked there) - revert doesn't revert history, only changes so it's no surprise. I didn't try cherry-picking the commits, how would that help me? – mikosz Nov 06 '12 at 10:02

1 Answers1

2

The graph you're trying to create doesn't make sensed from git's point of view. Specifically, making C1 a merge of ~C and b is weird because their merge-base is b, so there's nothing to do.

If you can't or won't do fast-forward pushes, then your best option is to re-create the merge and create a commit C1 in the place where ~C now stands. Call it "fix botched conflict resolutions" and be done with it - no need for additional merge confusion.

To create such a commit, first create the correctly-merged commit C1, and then run something like:

git reset --hard $(git commit-tree -p C -m "fix botched conflict resolutions" C1:)

See this answer for explanation of that line.

Community
  • 1
  • 1
user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • 1
    Looks like a thing that could work, but I get "fatal: Not a valid object name -p". When I rephrase the commit-tree command to "git commit-tree 3b66f18a1: -p 4eb2e3d0b7a7 -m 'fix botched conflict resolutions'" I get "usage: git commit-tree [(-p )...] < changelog" and am at a loss at this point... – mikosz Nov 06 '12 at 10:20
  • 1
    @MikolajRadwan You have an older version of git whose `commit-tree` doesn't support the `-m` switch, so you must spell the inner command as `echo "fix botched conflict resolutions" | git commit-tree 3b66f18a1: -p 4eb2e3d0b7a7`. – user4815162342 Nov 07 '12 at 13:27