简体   繁体   English

Git:如何在不覆盖历史记录的情况下还原分支合并?

[英]Git: how to revert a branch merge without overwriting history?

I have two branches: master and opengl . 我有两个分支: masteropengl I recently finished implementation (or at least I thought so) of opengl branch and decided to merge it into master : 我最近完成了opengl分支的实现(或者至少是这样想的),并决定将其合并到master

git checkout master
git merge opengl
git push

After I did this, several developers who are working on the master branch pulled my changes and it turned out that my implementation conflicted with some of their code. 完成此操作后,正在master分支上工作的几个开发人员撤消了我的更改,结果发现我的实现与他们的某些代码冲突。 Therefore I would like to revert the merge operation on the master branch, but without overwriting history. 因此,我想还原master分支上的合并操作,但不覆盖历史记录。

Note that I would like to be able to merge the opengl branch into master eventually (after I fix all the bugs). 请注意,我希望最终能够将opengl分支合并到master (修复所有错误之后)。 Therefore simply checking out older version of master and committing it will not work - newly created commit will cancel my changes from opengl when I will try to merge it. 因此,简单地检出较旧版本的master并提交将不起作用-当我尝试合并它时,新创建的提交将取消对opengl更改。

Thank you. 谢谢。

The documentation " How to revert a faulty merge " mentioned by cebewee explains why a git revert is tricky when reverting a merge. cebewee提到的文档“ 如何还原错误的合并 ”解释了为什么在还原合并时git revert会很棘手。

So the merge will still exist , and it will still be seen as joining the two branches together, and future merges will see that merge as the last shared state - and the revert that reverted the merge brought in will not affect that at all. 因此,合并仍将存在 ,并且仍将其视为将两个分支结合在一起,并且将来的合并将把合并视为最后一个共享状态-还原引入的合并的还原将完全不影响此状态。
If you think of "revert" as "undo", then you're going to always miss this part of reverts. 如果您将“还原”视为“撤消”,那么您将总是会错过这部分还原。
Yes, it undoes the data, but no, it doesn't undo history. 是的,它撤消数据,但是不,它不会撤消历史记录。

git revert is the right solution here, but it will have a consequence in the future, when you want to merge that branch again. git revert是这里的正确解决方案,但是当您想再次合并该分支时,它将在将来产生影响。
The next merge will then have to "revert the revert" first, and then merge the branch. 然后,下一个合并将必须首先“还原还原”,然后合并分支。

Edit: This turns out not to be what the OP asked for, but I'll keep it here in case someone should happen to look for a solution that does involve rewriting history. 编辑:事实证明这不是 OP所要求的,但是我将其保留在这里,以防万一有人要寻找确实涉及重写历史记录的解决方案。


First, create a new branch if you want to keep the merge commit locally, so that the commit doesn't "disappear" after you move master : 首先,如果您想将合并提交保留在本地,请创建一个新分支,以使提交在移动master之后不会“消失”:

git branch erroneousMerge master

If the other developers have also made commits after the erroneous merge, they must do this as well! 如果其他开发人员在错误合并之后也提交了内容,那么他​​们也必须这样做!

Then, reset master to refer to the last commit before the merge; 然后,将master重置为引用合并之前的最后一个提交; let's say that it's commit e498b2... : 假设它是提交e498b2...

git checkout e498b2
git branch -f master

Now, you can push the corrected master ( -f indicates that you want to make the server reset its master branch to the commit that you have made it point to, even though this commit is an ancestor of the one it points to in the repository): 现在,您可以推送更正的master-f表示您希望使服务器将其master分支重置为您指向它的提交,即使此提交是它在存储库中指向的提交的祖先):

git push -f origin master

Now, the other developers can update their master to match that of the server( -f indicates that they accept that the branch has moved backwards): 现在,其他开发人员可以更新master以匹配服务器的master-f表示他们接受分支已向后移动):

git fetch -f origin master:master

If the other developers have made changes after the erroneous merge (let's say that the merge commit is abc123 , they can use rebase to move the changes to the corrected master : 如果其他开发人员在错误合并之后进行了更改(假设合并提交为abc123 ,则他们可以使用rebase将更改移至更正后的master

git rebase --onto master abc123 oldMaster

If you screw up at some point and end up with "losing" commits because there is no longer any branches pointing to them, you can use git fsck --lost-found to recover them. 如果由于某个分支不再指向它们而在某个时候搞砸了并最终导致“丢失”提交,则可以使用git fsck --lost-found恢复它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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