0

I have a very specific case with Git that i need help getting through. A branch with some heavy alterations was merged to master a few weeks ago, and now, it needs to go away. However, we don't want to lose some other commits made to master, that have nothing to do with that other branch.

How can we remove the branch merge and re-apply other commits on top of the new HEAD?

vinnylinux
  • 7,050
  • 13
  • 61
  • 127

3 Answers3

1

The best way is just to revert the merge, by using git revert.

git help revert says:

  -m parent-number, --mainline parent-number
      Usually you cannot revert a merge because you do not know which side of the
      merge should be considered the mainline. This option specifies the parent
      number (starting from 1) of the mainline and allows revert to reverse the
      change relative to the specified parent.

      Reverting a merge commit declares that you will never want the tree changes
      brought in by the merge. As a result, later merges will only bring in tree
      changes introduced by commits that are not ancestors of the previously
      reverted merge. This may or may not be what you want.

      See the revert-a-faulty-merge How-To[1] for more details.

If you really want to change history to remove the merge from history and you are really aware of all the consequences you can use git rebase to do so:

git rebase --onto $good_commit $merge_commit branch

whereas merge_commit is the faulty merge commit and good_comit its known-good parent.

Be aware that in both cases it might be difficult to do so in case the newer commits changed code introduced by the merge commit.

michas
  • 25,361
  • 15
  • 76
  • 121
  • 1
    Note that reverting a merge commit doesn't revert the merge. It only undoes the changes that were introduced by the merge commit. The branch is still considered merged and therefore future merge attempts will appear to fail because there will be no unmerged changes. – Ryan Stewart Jun 01 '13 at 13:07
0

With what you described, it sounds like all the changes from alteration_branch are on master. Normally deleting a branch by git branch -d alteration_branch will not remove history if you don't supply the force option. I suggest just trying deleting it.

cforbish
  • 8,567
  • 3
  • 28
  • 32
0

Personally, I'd create a couple of temporary branches that start at the two split (base) points (one for the old branch, and one on master just before the merge). I'd create two branches at the tip of master, and then interactive rebase 'master' (actually those two tip branches) onto those two temporary base split branches to create the order you require by picking the right commits out of the rebase todo lists. Do remember to include any changes that happened across the merge (check the rebase options as merges are ignored by default)

Now you should have two new, separate, lines of development that represent your desired outcome. Repeat the process if it doesn't.

Finally do a forced update of the two branch refs (e.g. git update-ref) for master and the branch before declaring a flag day when you push the update and everybody has to do a forced pull (the never re-write history day)

Philip Oakley
  • 13,333
  • 9
  • 48
  • 71