Search code examples
gitgit-revertgit-cherry-pick

Undoing some merges/commits, but keeping some


I have a bad merge, followed by a couple of good commits. I tried to revert the bad merge, however I do not want to loose these changes (i.e. I do not want a further commit, which undoes the changes), I just dont want them in my branch.

So my log looks something like this:

7975c057 | Reverts bad merge
40a01d2f | Good commit
3b2c3825 | Good commit
1f3f1858 | Bad merge - code shouldnt be in this branch
37f71a89 | Good commit
... (more good commits...)

How can I remove 1f3f1858 | Bad merge and 7975c057 | Reverts bad merge from my branch?


Solution

  • Reverting a merge commit is tricky, because a merge has two parents, and the path of only one parent can be followed. If using an interactive rebase, you would typically have to redo the merge entirely. For this reason, I might suggest the following strategy:

    git checkout -b good_branch 37f71a89    # create new branch from 37f71a89
    git cherry-pick 3b2c3825                # cherry-pick first good commit
    git cherry-pick 40a01d2f                # cherry-pick second good commit
    

    This would leave you with the branch structure you want, though the two "good" commits would actually have new SHA-1 hash values, because cherry-picking always creates a new commit (though the commits would be functionally identical to their original counterparts).