CVS合并算法

时间:2009-09-14 20:02:58

标签: merge diff cvs

CVS在合并两个分支时使用什么算法(使用-j)?

  • 是否知道CVS标记,分支或日期?
  • 它只是做一个纯文本差异(例如,使用unix diff工具)吗?
  • 是使用2路还是3路差异?
  • 如果它使用3路差异,它使用的基本版本是什么?

由于

3 个答案:

答案 0 :(得分:6)

我记得前一段时间读过CVS合并实际上是使用diff3算法来执行合并。

宾夕法尼亚大学的这篇PDF文章A Formal Investigation of Diff3, by Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce详细介绍了diff3算法。

如果主要关注合并算法本身的属性,而不是它如何与CVS集成。

回答你的问题:

标签,日期意识

从CVS手册页:

  

-j tag [:date]合并来自tag或者when指定的修订的更改   指定了日期,标签是分支   tag,分支标记的版本   因为它存在于日期

2或3路和文本/二进制感知

diff3默认为纯文本差异。它比较(差异)文件的3个版本。

来自diff3手册页:

  

如果`diff3'认为任​​何一个   它正在比较的文件是二进制文件(a   非文本文件),它通常报告一个   错误,因为这样的比较是   通常没用。与'diff'一样,    你可以强迫'diff3'考虑所有   文件是文本文件并进行比较   它们通过使用'-a'或逐行排列   ' - text'选项。

比较期间的基本版本

根据链接文章,基本版本是文件的两个当前版本(A和B)之间的最后一个通用版本(O)。它首先使用2路差分算法来找到O和A以及O和B之间最长的公共子序列。

然后(引自文章)它:

  

......占据O的地区   不同于A或B和   合并重叠的,   导致交替序列   稳定(所有复制品相等)和   不稳定(一个或两个副本   改变了图1(c)所示的块.3   最后,它检查了已发生的变化   在每个块中并确定哪些更改   可以传播,如图所示   1(d) - 其中,第二个块被改变   只在A(插入4,5),所以这个   变化可以传播到B,但是   第四个块在A和A都有变化   B,所以没有任何东西可以传播。

答案 1 :(得分:3)

您可以使用两种不同形式的“合并”命令,这些命令略有不同:

  1. cvs up -j TAG
  2. cvs up -j TAG1 -j TAG2
  3. 变体之间的区别在于如何选择“基础”修订,但是任一变体的基本算法是对于每个文件,由CVS选择的两个修订之间的差异应用于当前工作副本之上。< / p>

    在第一种形式中,合并基础是给定TAG的共同祖先和工作副本修订。因此,假设您的本地修订版是1.38(HEAD上的#38)并且您正在合并1.34.4.2(HEAD上版本#34的分支4上的第2版) - 共同的祖先将是1.34。我相信这个变体使用两个差异1.34..1.38和1.34..1.34.4.2进行3向合并,在它们不匹配时产生冲突。

    在第二种形式中,您自己指定基本修订版,因此除了从CVS获取冲突标记外,最终结果与cvs diff -r TAG1 -r TAG2 | patch大致相同。

答案 2 :(得分:0)

CVS使用三个文件修订版,将两者之间的差异合并为第三个。除了签出的三个文件之外,实际合并不使用任何信息。您可以在CVS源代码中查看详细信息。有问题的函数是RCS_merge中的src/rcscmds.c,它使用call_diff3中的diff/diff3.c(或类似内容)。当然,您可以通过自己查找CVS来源来满足您的好奇心。