Search code examples
gitgithubgitlab-civersioning

Git rebasing for a branch with multiple merge commits


I am trying to break an older commit into more commits. The branch is pretty big and has more merge commits along the way. A simplification:

HEAD

A---B---merge_commit---C---merge_commit---D

In the above case, I want to split D into two commits.

I am currently doing:

git rebase -i D --rebase-merges
git reset HEAD~
'split into the two commits'
git commit 1
git commit 2
git rebase --continue

The problem is that I am getting conflicts at the merge conflicts and I tried with strategies (ours, theirs) and even manually but I can't get the branch after the rebase is finished to look like the branch before the rebase (git diff shows differences)

Any ideas on how could I solve this?

Thanks a lot.


Solution

  • When you're only rewriting ancestry, git filter-branch is your friend.

    # in a scratch clone:
    git clone -ns . $(mktemp -d); cd $_
    
    git checkout D
    git reset --patch @^  # to remove the bits that go in the next commit
    git commit --amend
    git commit -a
    
    # now that you've got the new commits you want in place of D,
    git replace D @
    git filter-branch -- $(git branch --contains D)
    

    and from there you can force-push the rewritten refs or just redo it in your original repo once you're sure you like all the rewrites it did or didn't do. This will run much faster than rebase.