Search code examples
gitgithubmergeversion-controlrebase

How to remove the past merge history in Git?


I have made a wrong merge in git and want to remove the past history about the merge from the local and one of the remote repositories. The figure shows the branch and commit history.

enter image description here

Here, prod branch contains some branch-specific information (say, db.yml). I have wrongly merged the prod branch to master. As a result, the remote repository of master now contains all the past commits between C and W. What I wanted was to keep the history of master clean of change of db.yml in prod branch.

In the figure above, what I want is to remove the indicated brown line so that the commit before X in master branch is commit B as far as the master branch is concerned, and the remote repository of master should not know of prod branch, which was branched out after commit B.

In other words, I want to remove the merge history from commit W to X in master branch only (which has been pushed to master repository), while I want to keep commits C to W in prod branch (which has a separate remote repository). In this case, a simple strategy of git rebase as explained in the past answer like this does not seem to work well. Or, is there a way?

How can I achieve this?


Solution

  • git checkout -B master B     # re-hang the `master` label on the commit before the oops
    git cherry-pick Y            # make the history it should have
    git checkout -B prod W       # likewise with `prod`: back to before the oops
    git merge master             # make the history it should have
    

    Unless you're in the habit of doing what often get called "evil merges", merges with unrelated changes mixed in, you don't want to keep X at all. It's the merge from prod to master.

    git push --force-with-lease origin master   # overwrite if nothing's changed since
    

    and likewise with prod if that lives there too.