mercurial - 退出 Mercurial 上的向后 merge

标签 mercurial merge dvcs branch

你如何在不痛苦的情况下逆转合并对极化分支的影响?

这个问题一直困扰着我我终于放弃了。

您有 1 个存储库,其中 2 个 命名 分支机构。 A 和 B。

A 发生的变化将不可避免地发生在 B 上。

直接发生在 B 上的更改绝不能发生在 A 上。

在这样的配置中,将“B”合并到“A”会在存储库中产生一个可怕的问题,因为对 B 的所有更改都出现在 A 中,就好像它们是在 A 中进行的一样。

从这种情况中恢复的唯一“正常”方法似乎是“退出”合并,即:

 hg up -r A 
 hg backout -r BadMergeRev --parent BadMergerevBeforeOnA 

看起来一切都很好,很花哨,直到您决定稍后在正确的方向上合并,并且您最终会发生各种令人讨厌的事情,并且在特定分支 B 上被删除/注释掉的代码突然变得未删除或未注释。

到目前为止,除了“让它做它的事情,然后手动修复所有问题”之外,还没有一个可行的可行解决方案,老实说,这有点令人费解。

这是一张说明问题的图片:

[原图丢失]

文件 C & E (或更改 C & E )必须只出现在分支 b 上,而不出现在分支 a 上。
此处的修订版 A9(分支 a,revno 9)是问题的开始。

修订版 A10 和 A11 是“退出合并”和“合并退出”阶段。

并且修订版 B12 是反复无常的,错误地反复删除不打算删除的更改。

这种困境引起了很多挫折和蓝烟,我想结束它。

注意

尝试禁止反向合并发生可能是显而易见的答案,无论是使用钩子(Hook)还是策略,我发现解决这个问题的能力相当高,而且发生的可能性很大,即使有对策,你仍然必须假设不可避免,它会发生,以便您可以在它发生时解决它。

详细说明

在模型中,我使用了单独的文件。这些使问题听起来很简单。这些仅代表可以是单独行的任意更改。

此外,雪上加霜的是,分支 A 上发生了重大变化,这留下了长期存在的问题“分支 A 中的变化是否与分支 B 中的变化发生冲突,后者刚刚出现(并退出),这看起来像是一个变化在分支 A 而不是“

关于历史重写技巧:

所有这些追溯解决方案的问题如下:
  • 我们有 9000 次提交。
  • 因此新鲜克隆需要半小时
  • 如果某个地方存在甚至一个存储库的错误克隆,它就有可能重新与原始存储库接触,并再次将其破坏。
  • 每个人都已经克隆了这个存储库,现在几天过去了,持续提交。
  • 一个这样的克隆,恰好是一个实时站点,所以“删除那个并从头开始”=“大诺诺”

  • (我承认,上面的许多内容都有些愚蠢,但它们超出了我的控制范围)。

    唯一可行的解​​决方案是假设人们可以并且将会做错任何事,并且有一种方法可以“消除”这种错误。

    最佳答案

    我想我找到了一个永久修复错误合并的解决方案,并且不需要您手动检查任何差异。诀窍是回到历史并生成与错误合并并行的提交。

    所以我们有一个存储库,每个维护版本的单个产品都有单独的分支。就像问题中提出的情况一样,在早期版本的分支上所做的所有更改(即该版本中的错误修复)最终都必须合并到更高版本的分支中。

    因此,具体而言,如果在 BRANCH_V8 上 checkin 了某些内容,则必须将其合并到 BRANCH_V9。

    现在其中一位开发人员犯了以下错误:他将 BRANCH_V9 中的所有更改合并到 BRANCH_V8(即错误方向的合并)。此外,在那个糟糕的合并之后,他在注意到自己的错误之前执行了一些额外的提交。

    所以情况如下面的图形日志所示。

    o BRANCH_V8 - 13 - 错误合并后的重要提交
    |
    o BRANCH_V8 - 12 - 从 BRANCH_V9 错误合并
    |\
    | o BRANCH_V8 - 11 - 添加对 BRANCH_V8 的评论(即最后已知的良好状态)
    | |
    ○ | BRANCH_V9 - 10 - 最后一次提交 BRANCH_V9
    | |

    我们可以按如下方式修复这个错误:

  • 将您的本地目录更新到 BRANCH_V8 的最后一个良好状态:hg update 11
  • 创建最后一个良好状态的新 child :
  • 更改一些文件 $EDITOR some/file.txt (这是必要的,因为 Mercurial 不允许空提交)
  • 提交这些更改 hg commit -m "generating commit on BRANCH_V8 to rectify wrong merge from BRANCH_V9"现在的情况如下:

    o BRANCH_V8 - 14 - 在 BRANCH_V8 上生成提交以纠正来自 BRANCH_V9 的错误合并
    |
    | o BRANCH_V8 - 13 - 错误合并后的重要提交
    | |
    | o BRANCH_V8 - 12 - 从 BRANCH_V9 错误合并
    |/|
    ○ | BRANCH_V8 - 11 - 添加对 BRANCH_V8 的评论
    | |
    | o BRANCH_V9 - 10 - BRANCH_V9 上的最后一次提交
  • 将新生成的 head 与发生错误合并的修订版合并,并在提交之前丢弃所有更改。 不要简单地合并两个头,因为您将丢失合并后发生的重要提交!
  • 合并:hg merge 12 (忽略任何冲突)
  • 丢弃所有更改:hg revert -a --no-backup -r 14
  • 提交更改:hg commit -m "throwing away wrong merge from BRANCH_V9"现在的情况如下:

    o BRANCH_V8 - 15 - 从 BRANCH_V9 中丢弃错误的合并
    |\
    | o BRANCH_V8 - 14 - 在 BRANCH_V8 上生成提交以纠正来自 BRANCH_V9 的错误合并
    | |
    +---o BRANCH_V8 - 13 - 错误合并后的重要提交
    | |
    ○ | BRANCH_V8 - 12 - 从 BRANCH_V9 错误合并
    |\|
    | o BRANCH_V8 - 11 - 添加对 BRANCH_V8 的评论
    | |
    ○ | BRANCH_V9 - 10 - 最后一次提交 BRANCH_V9
    | |

  • 即。 BRANCH_V8 上有两个头:一个包含错误合并的修复,另一个包含在合并后立即发生的 BRANCH_V8 上遗留的重要提交。
  • 合并 BRANCH_V8 上的两个头:
  • 合并:hg merge
  • 提交:hg commit -m "merged two heads used to revert from bad merge"

  • 现在 BRANCH_V8 上的情况最终得到纠正,如下所示:

    o BRANCH_V8 - 16 - 合并用于从错误合并中恢复的两个头
    |\
    | o BRANCH_V8 - 15 - 从 BRANCH_V9 中丢弃错误的合并
    | |\
    | | o BRANCH_V8 - 14 - 在 BRANCH_V8 上生成提交以纠正来自 BRANCH_V9 的错误合并
    | | |
    ○ | | BRANCH_V8 - 13 - 错误合并后的重要提交
    |//
    ○ | BRANCH_V8 - 12 - 从 BRANCH_V9 错误合并
    |\|
    | o BRANCH_V8 - 11 - 添加对 BRANCH_V8 的评论
    | |
    ○ | BRANCH_V9 - 10 - 最后一次提交 BRANCH_V9
    | |

    现在 BRANCH_V8 上的情况是正确的。剩下的唯一问题是从 BRANCH_V8 到 BRANCH_V9 的下一次合并将是不正确的,因为它也会在错误合并的“修复”中合并,这是我们不希望在 BRANCH_V9 上发生的。这里的技巧是在单独的更改中从 BRANCH_V8 合并到 BRANCH_V9 :
  • 首先合并,从 BRANCH_V8 到 BRANCH_V9,BRANCH_V8 上从错误合并之前的正确更改。
  • 在合并错误及其修复中进行第二次合并,无需检查任何内容,丢弃所有更改
  • 第三,合并来自 BRANCH_V8 的其余更改。

  • 详细说明:
  • 将您的工作目录切换到 BRANCH_V9 :hg update BRANCH_V9
  • 合并 BRANCH_V8 的最后一个良好状态(即您为修复错误合并而生成的提交)。这个合并是一个像任何常规合并一样的合并,即。冲突应该像往常一样解决,什么都不需要扔掉。
  • 合并:hg merge 14
  • 提交:hg commit -m "Merging in last good state of BRANCH_V8"现在的情况是:

    @ BRANCH_V9 - 17 - 合并到 BRANCH_V8 的最后一个良好状态
    |\
    | | o BRANCH_V8 - 16 - 合并用于从错误合并中恢复的两个头
    | | |\
    | +---o BRANCH_V8 - 15 - 从 BRANCH_V9 中丢弃错误的合并
    | | | |
    | ○ | | BRANCH_V8 - 14 - 在 BRANCH_V8 上生成提交以纠正来自 BRANCH_V9 的错误合并
    | | | |
    | | ○ | BRANCH_V8 - 13 - 错误合并后的重要提交
    | | |/
    +---o BRANCH_V8 - 12 - 从 BRANCH_V9 错误合并
    | |/
    | o BRANCH_V8 - 11 - 添加对 BRANCH_V8 的评论
    | |
    ○ | BRANCH_V9 - 10 - 最后一次提交 BRANCH_V9
    | |
  • 合并 BRANCH_V8 上的错误合并 + 其修复,并丢弃所有更改:
  • 合并:hg merge 15
  • 还原所有更改:hg revert -a --no-backup -r 17
  • 提交合并:hg commit -m "Merging in bad merge from BRANCH_V8 and its fix and throwing it all away"现在的情况 :

    @ BRANCH_V9 - 18 - 合并来自 BRANCH_V8 的错误合并及其修复并将其全部丢弃
    |\
    | o BRANCH_V9 - 17 - 合并到 BRANCH_V8 的最后一个良好状态
    | |\
    +-----o BRANCH_V8 - 16 - 合并两个头,用于从错误合并中恢复
    | | | |
    o---+ | BRANCH_V8 - 15 - 从 BRANCH_V9 中丢弃错误的合并
    | | | |
    | | ○ | BRANCH_V8 - 14 - 在 BRANCH_V8 上生成提交以纠正来自 BRANCH_V9 的错误合并
    | | | |
    +-----o BRANCH_V8 - 13 - 错误合并后的重要提交
    | | |
    o---+ BRANCH_V8 - 12 - 从 BRANCH_V9 错误合并
    |//
    | o BRANCH_V8 - 11 - 添加对 BRANCH_V8 的评论
    | |
    ○ | BRANCH_V9 - 10 - 最后一次提交 BRANCH_V9
    | |
  • 合并来自 BRANCH_V8 的剩余更改:
  • 合并:hg merge BRANCH_V8
  • 提交:hg commit -m "merging changes from BRANCH_V8"

  • 最终情况是这样的:

    @ BRANCH_V9 - 19 - 合并来自 BRANCH_V8 的更改
    |\
    | o BRANCH_V9 - 18 - 合并来自 BRANCH_V8 的错误合并及其修复并将其全部丢弃
    | |\
    | | o BRANCH_V9 - 17 - 合并到 BRANCH_V8 的最后一个良好状态
    | | |\
    ○ | | | BRANCH_V8 - 16 - 合并两个用于从错误合并中恢复的头
    |\| | |
    | o---+ BRANCH_V8 - 15 - 从 BRANCH_V9 中丢弃错误的合并
    | | | |
    | | | o BRANCH_V8 - 14 - 在 BRANCH_V8 上生成提交以纠正来自 BRANCH_V9 的错误合并
    | | | |
    ○ | | | BRANCH_V8 - 13 - 错误合并后的重要提交
    |///
    o---+ BRANCH_V8 - 12 - 从 BRANCH_V9 错误合并
    |//
    | o BRANCH_V8 - 11 - 添加对 BRANCH_V8 的评论
    | |
    ○ | BRANCH_V9 - 10 - 最后一次提交 BRANCH_V9
    | |

    在所有这些步骤中,您不必手动检查任何差异,BRANCH_V8 和 BRANCH_V9 是正确的,并且将来从 BRANCH_V8 到 BRANCH_V9 的合并也是正确的。

    关于mercurial - 退出 Mercurial 上的向后 merge ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/265944/

    相关文章:

    mercurial - 在 Mercurial 中使用 subrepos

    svn - 当使用 svn cp 或 svn mv 时,如何使 svn diff 生成补丁将应用的文件?

    git - 如何显示已上演的更改?

    macos - 适用于Mac的良好Mercurial存储库查看器

    mercurial - Mercurial 中未添加文件夹

    Mercurial rebase 场景

    Mercurial - 在新代码提示之上重新设置旧代码分支,忽略分支与旧代码的 merge

    R根据其引用列将特定列从一个数据帧合并到另一个数据帧

    python - 如何将列表合并到元组列表中?

    ssl - 带有指纹的 www.bitbucket.org 证书在推送更改时未验证问题