How to revert a merge which used strategy=ours?

烈酒焚心 提交于 2020-01-02 01:46:37

问题


I'm working with a repository where a merge was performed weeks ago which we just discovered used the --strategy=ours flag (it was supposed to use the --strategy-option=ours flag), thus not applying any changes to HEAD. However, we need to have the changes applied. Git already recognizes the branch as being merged and the commits in the history of the branch.

This sort of merge can't be reverted using git revert -m ...

What would be the proper way of reverting and/or re-applying the merge to change the files?

master  A - B - E - F - G ---> L - M - N
             \     /
topic         C - D

Merge commit (F) would be the culprit in this scenario.


回答1:


I have discovered a solution to this problem. It was all in the letter that Linus wrote regarding reverting faulty merges: How to revert a faulty merge. The git merge --strategy=ours topic in our case was not intended. Even though it's a faulty merge, it can't be reverted, and having long been pushed, has the same effect of having a revert merge commit without being able to revert the revert commit.

The solution was to checkout the topic branch, run rebase --no-ff from the first commit and then merge that branch back into master.

git checkout topic
git rebase -i --no-ff <C>
git checkout master
git merge topic

This had the effect of yielding:

fixed–topic   C'–––D'––––––––––––––––––––-
             /                            \
master  A–––B–––E–––F–––G –––> L–––M–––N–––F2
             \     /
topic         C–––D

To really understand this in-depth, read the last portion of the letter How to Revert a Faulty Merge using the --no-ff rebase option to re-create the branch.




回答2:


@Highway of Life has a great answer. The one thing is that the rebased commits now look like new different commits, which in many cases may be undesirable. I wanted to merge the identical commits a second time, but git-merge prevents this. However, I find time and again that it is always possible to get git to do what you want.

  1. Follow Highway of Life's instructions but don't merge straight onto master:

    git checkout -b fixed-topic <D>
    git rebase -i --no-ff <B>
    git checkout -b re-merged master
    git merge fixed-topic
    

    This results in:

    re-merged               ––––––––––––––––––––------R
                           /                         /
    fixed–topic      C'–––D'                        /
                    /                              /
    master     A–––B–––E–––F–––G –––> L–––M–––N–––F2
                    \     /
    topic            C–––D
    
  2. Now the tree is set up exactly how you want—all the files show exactly the contents you desire. The one problem is that your merge commit's parents are rebased copies of your original commits, instead of actually being the original commits themselves. It's easy to fix this with git-reparent:

    git reparent -p master -p <D>
    

    This ends up with:

    master     A–––B–––E–––F–––G –––> L–––M–––N–––F2
                    \     /                        \
    topic            C–––D                          \
                          \                          \
    re-merged              ---------------------------R
    

    An important thing to note is that the contents of R haven't changed since the last step—only the parents.

  3. Fast-forward master to the new merge commit:

    git checkout master
    git merge re-merged
    
  4. Finally you can clean up with

    git branch -d fixed-topic re-master
    

Done! Now your history looks like this, with one branch merged twice:

master  A–––B–––E–––F–––G –––> L–––M–––N–––F2---R
             \     /                           /
topic         C–––D----------------------------



回答3:


a merge strategy that says "keep what you have here no matter what you're merging in" by it's nature cannot be reversed. Checkout the 1st parent of the merge in a new branch, then do the merge again. Rebase --onto the rest of the commits you have on top of your original merge onto this one.

UPDATE:

In your case, if you don't care about the past, you can rebase G-N onto E and then just merge D onto this new master. The rebase will be trivial because F was an --ours merge.



来源:https://stackoverflow.com/questions/14225829/how-to-revert-a-merge-which-used-strategy-ours

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!