Git:如何在不覆盖历史记录的情况下恢复分支合并?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5383659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git: how to revert a branch merge without overwriting history?
提问by Sergiy Belozorov
I have two branches: master
and opengl
. I recently finished implementation (or at least I thought so) of opengl
branch and decided to merge it into master
:
我有两个分支:master
和opengl
。我最近完成了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. Therefore I would like to revert the merge operation on the master
branch, but without overwriting history.
在我这样做之后,在master
分支上工作的几个开发人员撤消了我的更改,结果发现我的实现与他们的一些代码发生了冲突。因此,我想恢复master
分支上的合并操作,但不覆盖历史记录。
Note that I would like to be able to merge the opengl
branch into master
eventually (after I fix all the bugs). 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.
请注意,我希望能够最终将opengl
分支合并master
(在我修复所有错误之后)。因此,简单地检查旧版本master
并提交它是行不通的 - 新创建的提交将从我opengl
尝试合并它时取消我的更改。
Thank you.
谢谢你。
回答by VonC
The documentation "How to revert a faulty merge" mentioned by cebeweeexplains 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.
The next merge will then have to "revert the revert" first, and then merge the branch.
git revert
在这里是正确的解决方案,但是当您想再次合并该分支时,它会在将来产生后果。
下一次合并将必须首先“还原还原”,然后合并分支。
回答by Aasmund Eldhuset
Edit:This turns out notto be what the OP asked for, but I'll keep it here in case someone should happen to look for a solution that doesinvolve 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; let's say that it's commit e498b2...
:
然后,重置master
以引用合并前的最后一次提交;假设它是 commit 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
以匹配服务器的(-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
它们来恢复它们。