代码之家  ›  专栏  ›  技术社区  ›  moswald Jarod42

一个多变的合并选择了错误的更改,什么是正确的方法来解决这个问题?

  •  10
  • moswald Jarod42  · 技术社区  · 15 年前

    已对.vcproj进行了更改,以修复生成计算机(变更集1700)上的问题。后来,一个开发人员将他的更改(从1710到1715的更改)合并到主干中,但是mercurial auto merge覆盖了1700的更改。我认为这是因为他选择了错误的分支作为合并的“父级”(参见问题的第2部分)。

    2) 为了确保不会发生这种情况,开发人员应该做些什么?我们有没有办法实施“正确”的方法?

    触摸.vcproj文件(不要靠近开发人员A所做的更改)。当开发人员B合并他的更改(成为1710到1715的更改)时,合并过程覆盖了1700的更改。

    为什么? Mercurial认为它不应该保留1700年的变化,不管是否有“官方”的方法来解决这个问题。

    2 回复  |  直到 15 年前
        1
  •  10
  •   StayOnTarget Charlie Flowers    9 年前

    我会先回答你问题的第二部分。。。

    如果有冲突,自动合并工具应该强制程序员决定合并的方式。但一般的假设是,冲突将涉及对同一组行的两次编辑。如果由于对彼此不接近的行的编辑而产生冲突,则自动合并将愉快地选择两个编辑,并出现错误。

    int i;  // Someone replaces this with 'short i' in one changeset stating
            // that a short is more efficient.
    
    // ...  lots of code;
    
    // Someone else replaces all the 65000s with 100000s in another changeset,
    // saying that more precision is needed.
    for (i = 0; i < 65000; ++i) {
        integral_approximation_piece(start + i/65000.0, end + (i + 1) / 65000.0);
    }
    

    没有合并工具会捕获这种冲突。该工具必须实际编译代码,以确保代码的这两部分相互关联,虽然在这种情况下这可能已经足够了,但我可以构造一个示例,要求运行代码并检查结果以捕获冲突。

    这意味着您真正应该做的是在合并后严格测试您的代码,就像在任何其他更改后一样。绝大多数合并将导致开发人员必须解决的明显冲突(即使该解决方案通常相当明显),或者将干净地合并。但极少数不符合这两个类别的合并无法以自动化的方式轻松处理。

    这也可以通过鼓励地方性的发展实践来解决。例如,一种编码标准,规定“变量应在其使用位置附近声明”。

    .vcproj 文件特别容易出现这个问题,因为开发人员不太了解它们,因此如果出现冲突,他们将不确定如何处理它们。我的猜测是这样的,你的开发人员只是做了一个回复到他签入的修订版。

    至于第一部分。。。

    在这种情况下要做什么在很大程度上取决于你的开发过程。您可以剥离合并变更集并重新执行它,但是如果很多人已经提取了合并变更集,那么这将不会很好地工作;如果已经签入了许多基于合并变更集的变更集,那么它的工作将特别糟糕。

    您还可以签入一个新的更改来修复合并的问题。

    这基本上是你的两个选择。

    在我看来,你的帖子的语气表明,你的组织中可能存在一些围绕这一问题的政治观点,人们将这一错误归咎于Mercurial的频繁合并。所以我要指出,任何变更控制系统都可能有这个问题。例如,在Subversion的情况下,每当开发人员在其工作目录中有未完成的更改时进行更新时,他们都在进行合并,任何合并都可能出现这种问题。

        2
  •  7
  •   Vadim Kotov First Zero    8 年前

    1. 哪两个变更集将构成这两个变更

    在这两个问题中,第一个非常重要,第二个几乎无关紧要,尽管我花了一段时间才明白这一点。

    您可以使用 hg update X . 改变了 hg parents hg summary )并在合并之前确定工作目录中的内容。

    您可以使用 hg merge Y . 也就是说合并X(工作目录的父目录)和变更集Y。作为一种特殊情况,如果存储库中只有两个头,并且父目录已经是其中一个,那么Y将默认为另一个。

    我必须查看结果图才能知道开发人员做了什么,但有可能在调用merge之前他没有更新到某个head或另一个head,这将使他将一个head与历史上的某个point合并。

    如果您的开发人员为合并选择了正确的父级,那么左与右并不重要——唯一真正的区别是当使用 hg diff hg log -p 或者显示合并变更集修补程序的其他命令,它相对于左父项显示。不过,这主要是一个因素,只在显示。从功能上来说,它们几乎是一样的。

    假设您的开发人员选择了正确的变更集,那么他应该在提交合并之前测试合并的结果。合并 软件开发,不是一个恼人的VCS副作用,而且在提交之前不进行测试是错误的。

    要解决这个问题,只需重新正确地进行合并。使用 hg update 若要设置一个父对象,请使用 hg merge hg strip 或者更好的办法是,用 hg commit --close-branch 更新后。

    避免

    你说“mercurial自动合并”,但mercurial并不是真正的自动合并。它做了一个 premerge 这是一个非常谨慎的组合明显的变化,但它是如此小心,它甚至不会合并为您,如果每个合并父添加代码在同一个地区,因为它不知道你宁愿有哪块代码首先。

    可以完全禁用此预合并,也可以使用合并工具配置选项逐个文件禁用此预合并:

    https://www.mercurial-scm.org/wiki/MergeToolConfiguration?highlight=premerge

    推荐文章