Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mercurial中的自动合并有多安全?_Mercurial_Merge - Fatal编程技术网

Mercurial中的自动合并有多安全?

Mercurial中的自动合并有多安全?,mercurial,merge,Mercurial,Merge,在Mercurial中,您可以使用它来模拟类似于svn update之类的内容,即在不查看传入更改的情况下与它们合并。但是,即使您不使用hgfetch,您的大多数合并也将“奇迹般地”工作,而不会导致冲突。这很好,但是相信这样的合并是(比如)Java代码的有效合并有多安全呢 是否有任何示例可以说明为什么或何时应该(或不应该)信任这些合并?好的,只要您不开始重新组织代码,它们是非常安全的 考虑以下示例: class A { public void methodA() { // do

在Mercurial中,您可以使用它来模拟类似于
svn update
之类的内容,即在不查看传入更改的情况下与它们合并。但是,即使您不使用
hgfetch
,您的大多数合并也将“奇迹般地”工作,而不会导致冲突。这很好,但是相信这样的合并是(比如)Java代码的有效合并有多安全呢


是否有任何示例可以说明为什么或何时应该(或不应该)信任这些合并?

好的,只要您不开始重新组织代码,它们是非常安全的

考虑以下示例:

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添加一些说明。
在这段时间里,一位同事决定不管出于什么原因,methodC都应该放在班上

您将得到两个要合并的版本。
你的:

还有你的同事:

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将要求您手动合并这些类。

如果您对合并过程有怀疑,马已经离开了马厩

协调发展只需要:协调。您不应该同时处理同一段代码。这是否意味着不在同一个函数、类或文件中工作取决于您的环境和更改的范围,这个主题太深,无法在此简单解释

关键是,如果您不知道您在进行更改时进行了良好的协调,那么无论是自动合并过程还是手动合并过程,无论多么顺利,都不能保证获得良好的结果。充其量,它可以告诉你,你最终没有在同一段代码中工作,但这对破坏你的代码,或者更糟糕的是,微妙地污染它的语义和逻辑变化来说,是不舒服的。这是正确的,无论它是否合并而没有抱怨,甚至它编译

最好的防御措施是测试套件,它允许您以自动化的方式检查最终产品。很清楚,这也是进行持续维护和开发的最佳方法之一

综上所述,我所做的大多数合并都顺利进行。在合并过程中,那些引起麻烦的代码被称为冲突,这足以告诉我们更仔细地研究所讨论的代码,但更重要的是,我们用来划分工作的技术。最好是把事情做好,但也很难知道什么是“对”,除非你把事情搞砸了几次。这并不意味着我们没有引入逻辑错误,我们没有测试所有代码,但世界也不是完美的

归根结底,Mercurial的合并过程与没有合并的过程相同,但比没有合并的过程要好,这是一个积极的结果。您可以跳过手动合并所有看似无害的内容,即使它们确实存在逻辑错误,您也可能会错过手动合并之类的粗略检查。它只是更快,并将注意力集中在那些冲突上,在任何情况下,这些冲突也是逻辑错误的最佳证据


唯一真正的答案是明确地预先协调您的工作,并投资于一种测试方法,例如带有单元测试的TDD。指责合并是一件很糟糕的事。

我已经在工作中使用Mercurial好几个月了。整个团队由50多名软件开发人员组成,分为5-10名开发人员组成的小组。我们尚未看到失败的合并不是由以下原因造成的:

  • 父文件在合并过程中被破坏/损坏(即:编码错误)
  • 开发人员错误地解决了合并冲突
  • 因此,我们对标准文本文件(.c、.h、.pl、makefile、linkerfile等)的合并结果非常满意

    我们已经确定了一种情况,在这种情况下,合并是一个坏主意,可能会导致一些问题,这涉及到自动生成的代码或模型被存储为文本文件。Mercurial不会尝试合并二进制文件,但它很乐意合并模型、自动生成的.c/.h文件等。您可以为每个目录或文件类型指定合并策略,但即使有了这些设置,由于Mercurial的premerge,也可能发生不适当的合并。除此之外,Hg合并对我们非常有效


    ps:如果您对型号/自动发电机案例感兴趣,请寻求建议

    合并提交与“常规”代码更改提交一样严重。因此,所有常规开发的规则也适用于合并。在合并过程中,没有什么魔法能让任何风投对代码做正确的事情,基本上他们使用复杂的文本搜索和替换算法将两个分支的更改放入输出文档中。只有当文本替换失败时,合并冲突才会出现,但当代码的语义出错时,合并冲突不会出现


    执行合并的开发人员必须确定这些更改是否正确,通常是通过审查与合并父项的差异来确定这些更改是否正确(,并检查软件是否编译,运行单元测试,并进行同行审查,以及……您知道这项演练)。

    我一直使用
    hg fetch
    。我让它自动拉/合并/提交,然后我构建+测试。如果失败,您可以
    hg退出上一个事务
    ,或者只是修复损坏的事务,然后在推送之前提交一个新的变更集。

    以您的示例为例,结果更糟:
    //这里您的奇妙更改
    methodB()
    结束。但是,您所有的
    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
       }
    
    }