如何执行git还原并删除合并历史记录?

时间:2015-08-10 04:10:13

标签: git git-merge git-revert

这个问题与How can you tell who merged which branch into git?有关。

基本上,develop在准备好之前意外合并到master ,导致master不稳定。然后master push编辑/ {{}}到各种机器。为了解决这个问题,我执行了pull来撤消更改而不了解命令的所有含义:数据更改将被撤消,但历史记录不会。也就是说,git revert以前的提交包含master的提交,这意味着将来当 准备将develop合并到develop时在发布master之前,develop上的任何有效提交都不会包含在合并中。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

简短的回答是你不能(同时还原#34;撤消"历史)。

可以做什么,但是,在一个新的,不同的临时分支(例如匿名分支)上重复合并,在该分支上从未发生过错合并。有关方法,请参阅this answer。然后,您可以使用生成的树进行"更正的合并"提交目标分支(在这种情况下为master)。这"纠正了合并" commit本身不是一个合并提交,只是一个普通的提交,但它会有你想要的内容

如果您想保留额外的"重新合并历史记录"你可以使它成为临时匿名分支的真正合并。这只是提供所需父提交ID的问题,无论是通过真正合并到master,伪造MERGE_HEAD文件,进行--ours合并到匿名分支,然后交换标签,或向git commit-tree提供正确的父母。 (具体细节取决于您希望如何进行--first-parent修订跟踪。)

请注意,如果需要,您可以在将其用于树之前,将其他提交添加到匿名分支中。或者,如果你选择"真正的合并"方法,您可以将临时分支结果合并到master

... - o - m - w - A - B - *    <-- master
        \/               /
        /\_____ M ______/      <-- temp-branch
       /       /
... - o - o - o                <-- develop

此处所有o都是无聊的普通提交,m是错误合并,w是其恢复,AB是提交在你想保留的主人身上(他们被显示为非合并提交,但他们可以合并:这里重要的部分是他们附加的树)。然后,M是临时分支上重新完成的正确合并,*是最终合并回master,之后您可以删除temp-branch标签同时在提交图中保留底层分支。在此特定方案中,您将使用这些命令(尽管我省略了所需的任何合并冲突解决方案):

$ git checkout -b temp-branch <master-commit-before-m>
$ git merge develop
$ git checkout master
$ git merge temp-branch  # be sure to fix up the merge message
$ git branch -d temp-branch

然后提交*的第一个父项为B,其第二个父项是提交M

这里的诀窍是记住你需要这样做,并在错误合并之前找到master(分支master的尖端的那个)的正确提交;它&#39;是错误合并m的第一个父级,你现在可以给它一个标签,或者现在给它一个分支名称,而你知道它在哪里,而不是在以后使用git checkout -b temp-branch <sha1>之后重新定位SHA-1,但如果这样做,请选择一个比temp-branch更有意义的名称!)。

&#34;记住你需要这样做&#34;真的是最难的部分。所有其余的只是与git一起讨论。