在Mercurial中,您可以使用fetch extension来模拟svn update
之类的内容,即在不查看内容的情况下合并传入的更改。但即使您不使用hg fetch
,您的大多数合并都会“奇迹般地”工作而不会导致冲突。这很好,但是相信Java代码的有效合并是否安全可信?
是否有任何示例来说明为什么或何时应该(或不应该)信任这些合并?
答案 0 :(得分:3)
嗯,只要你不开始重新组织代码,它们就非常安全。
考虑以下示例:
class A {
public void methodA() {
// do something here
// that should be great
}
public void methodB() {
// And now I'll
// do something here
// and it's gonna be good.
}
public void methodC() {
// Finally, let's
// do something here
}
}
现在,您开始工作并决定向methodC添加一些指令 在此期间,一位同事认为,无论出于何种原因,方法C都应放在课堂上。
您最终将合并两个版本 你的:
class A {
public void methodA() {
// do something here
// that should be great
}
public void methodB() {
// And now I'll
// do something here
// and it's gonna be good.
}
public void methodC() {
// Finally, let's
// do something here
// and here your marvelous changes
}
}
你的同事:
class A {
public void methodC() {
// Finally, let's
// do something here
}
public void methodA() {
// do something here
// that should be great
}
public void methodB() {
// And now I'll
// do something here
// and it's gonna be good.
}
}
当合并发生时,由于默认上下文是三行宽,自动合并可能会认为有效结果是这个:
class A {
public void methodC() {
// Finally, let's
// do something here
}
public void methodA() {
// do something here
// that should be great
}
public void methodB() {
// And now I'll
// do something here
// and it's gonna be good.
}
public void methodC() {
// Finally, let's
// do something here
// and here your marvelous changes
}
}
出于这个原因,如果可能的话,我会尝试保持方法有条理,以便访问者被分组,并且不受影响,私有部分按照共同逻辑分组等等......但并非总是可行。
希望这种情况非常罕见,如果有太多更改,mercurial会要求您手动合并这些类。
答案 1 :(得分:2)
我已经在Mercurial工作了好几个月了。整个团队由50多名软件开发人员组成 - 分为5-10名开发人员。我们还没有看到一个失败的合并,而不是以下结果:
因此,我们对标准文本文件(.c,.h,.pl,makefile,linkerfiles等)的合并结果非常满意。
我们已经确定了一个案例,其中合并是个坏主意并且可能导致一些问题,这涉及自动生成的代码或模型存储为文本文件。 Mercurial不会尝试合并二进制文件,但它会愉快地合并模型,自动生成的.c / .h文件等。您可以为每个目录或文件类型指定合并策略,但即使使用这些设置,也可能由于Mercurial的预合并而发生不适当的合并。在这些情况之外,汞合并对我们非常有效。
ps:如果您对模型/自动生成案例感兴趣,请找一个建议here。
答案 2 :(得分:2)
合并提交与“常规”代码更改提交一样严重。因此,常规开发的所有规则也适用于合并。没有任何魔法使得任何VCS在合并期间使用代码做正确的事情,基本上他们使用复杂的文本搜索和替换算法将两个分支的更改放入输出文档中。合并冲突仅在文本替换失败时出现,而不是在代码的语义出错时出现。
执行合并的开发人员必须确定这些更改是否正确,通常是通过查看与两者合并父项的差异(并检查软件是否已编译,运行单元测试以及具有同行评审,......你知道演练。
答案 3 :(得分:2)
我一直使用hg fetch
。我让它自动拉/合并/提交然后我构建+测试。如果失败,你可以hg backout
最后一次交易,或者只修复坏了,然后在推送之前提交一个新的变更集。
答案 4 :(得分:-3)
如果你对合并过程持怀疑态度,马已经离开了谷仓。
协调发展只需要:协调。您不应该同时处理相同的代码段。这是否意味着不在同一个函数,类或文件中工作取决于您的环境和更改的范围,这个主题太深,无法在此处进行简单的解释。
关键是,如果你不知道你通过良好的协调来确定变化,那么无论是自动合并过程还是手动过程,无论如何顺利,都不能保证良好的结果。最好的情况是它可以告诉你,你最终没有在同一段代码中工作,但这对于破坏你的代码的语义和逻辑变化是不利的,或者更糟糕的是,巧妙地污染它。无论是否在没有投诉的情况下合并,或者即使它被编译,都是如此。
最好的防御是测试套件,它允许您以自动方式检查最终产品。 Lucikily,无论如何,这也恰好是持续维护和开发的最佳方法之一。
所有这一切,我所做的大多数合并都顺利完成了。导致麻烦的那些在合并过程中被称为冲突,这足以告诉我们更仔细地查看有问题的代码,而且更重要的是,我们用来分割我们工作的技术。最好让它正确进入,但在你搞砸了几次之前,也很难知道“正确”是什么。这并不意味着我们没有引入逻辑错误,我们也没有测试所有代码,但世界也不完美。
归结为Mercurial的合并过程与没有它的过程相同但更好,净积极。你可以跳过手动合并所有看起来无害的东西,即使它们确实有逻辑错误,你可能会错过粗略的检查,如手动合并。它只是更快,并且对那些冲突的人来说是零,这对于逻辑错误来说也是最好的吸烟枪。
唯一真正的答案是明确协调您的工作并投资测试方法,例如TDD和单元测试。归咎于合并是不够的。