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

Posted

技术标签:

【中文标题】如何执行 git revert 并删除合并历史记录?【英文标题】:How can you perform a git revert AND remove the merge history? 【发布时间】:2015-11-01 21:24:38 【问题描述】:

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

基本上,develop 被意外合并到master 我们准备好之前,导致master 不稳定。 master 然后pushed/pulled 到各种机器。为了解决这个问题,我执行了git revert 来撤消更改,但没有了解该命令的所有含义:data 更改将被撤消,但 history强>不会。即,master 的先前提交包括 develop 的提交,这意味着将来当我们准备准备将 develop 合并到 master 时,之前在 develop 上的任何有效提交发出git revert 将不会包含在合并中。

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

简短的回答是您不能(还原并同时“撤消”历史记录)。

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

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

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

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

这里所有的os 都是无聊的普通提交,m 是错误的合并,w 是它的反转,AB 是你希望保留的 master 提交(它们'重新显示为非合并提交,但它们可以合并:这里的重要部分是它们附加的树)。然后,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 的尖端;它是错误合并@ 的第一个父项987654345@,你现在可以给它一个标签,甚至现在给它一个分支名称,而你知道它在哪里,而不是在必须重新定位 SHA-1 之后使用git checkout -b temp-branch &lt;sha1&gt;——但如果你这样做了这个,选择一个比temp-branch更有意义的名字!)。

“记住你需要这样做”确实是最难的部分。其余的都只是用 git 大惊小怪。

【讨论】:

以上是关于如何执行 git revert 并删除合并历史记录?的主要内容,如果未能解决你的问题,请参考以下文章

如果合并或重新定位,则主删除分支文件中的 Git `revert`

git:清理 git 历史记录并仅在 master 中保留合并的提交

删除 git 历史记录中包含合并的特定提交

在 master 上清理 git 历史记录的正确方法

如何将多个 Git 存储库合并为一个并交错历史

如何在选定点之前删除 git 历史记录