简体   繁体   中英

How to force a merge even if git shows "Already up to date."

About half a year ago one of the developers screwed up and merged a branch he was not supposed to (our alpha tests branch) into master. We quickly fixed the issue by reverting the merge.

Fast forward 6 months, today I am trying to merge one of the branches that landed on master in that bad merge, but git is saying that I cannot. Changes from that branch are not on master, but git does not allow merging.

Is there a way to force a merge?

Changes from that branch are not on master

The "changes" from that branch are not on master , because reverting the merge commit reversed those changes. But the commits from that branch are on master . Reverting the merge commit did nothing about that; it didn't change the topology:

A -- B -- C -- D -- M -- Mrevert -- E ... (master)
      \           /
       X -- Y -- Z

Do you see? X, Y, and Z are still on master . So they can never be merged into master again. That train has left the station.

What you can do is cherry pick X, Y, and Z into a new branch and merge that . That's because cherry pick makes new commits that are not the same as the ones that have been merged. (Or, as Romain Valeri has suggested, just make a branch that contains a commit that reverts the revert, and merge that .)

For more information, see, always see, Linus Torvald's own explanation of this situation and what your options are:

https://github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt

As an easy workaround to this problem, you can rewrite the revisions that make up that branch so that to git they are not the same revisions that were merged. Assuming that branch is a straight line that started on revision X (X being the first revision that belongs to this feature branch, separate from the common branch) and that the branch is called the-branch , you can do:

git checkout X~ # keep the pig tail when writing the revision
git cherry-pick HEAD..the-branch
# now you have the exact same revisions that make up the-branch but they are _clones_ of the original revisions....
# to git, they are _not_ the same revisions
git branch -f the-branch # set the-branch over here
git checkout main-branch
git merge the-branch # git will not complain

PS I just noticed that this is basically matt's answer (which I have just upvoted), only that I have written down the steps for anyone to read.

From what others said looks like its impossible to do a forced merge.
It seems that depending on your situation you have to follow different paths.

  1. If you merged a branch, then reverted it, then you want to remerge the same branch, go with @matt solution
  2. If you, like in my case, merged a branch that contained multiple other branches merged, reverted it, and now you want to merge only one of those branches, you can use this solution.
  3. If you are merging into non-master branch then you can use the rebase -ff method suggested by Linus, but the downside will be lost branching history

This solutions will work only for merging to master, since merging ot anything else would pollute your feature branch with contents of target branch.

Solution is to merge master back into your feature branch and then replay the history using cherry picks like this:

A -- B -- C -- D -- M -- <revert M> -- E -- ............ -- M' (master)
      \           /          \                             /
       X -- Y -- Z -- ... -- <Merge master> -- X -- Y -- Z

After merging master to feature branch you are back to having that branch empty, then cherry picking commits X, Y, Z you are back to the same situation you were in before the first merge. You can then apply any changes you need and then merge again.

This way you will keep the changes history (though somehow polluted) and will be able to remerge.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM