CVS合并算法

发布于 2024-08-04 07:19:03 字数 190 浏览 1 评论 0原文

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

  • CVS 标记、分支或日期是否可识别?
  • 它只是进行纯文本比较(例如,使用 unix diff 工具)吗?
  • 它使用 2 路还是 3 路差异?
  • 如果它使用 3 路 diff,它使用的基本版本是什么?

谢谢

What algorithm does CVS use when merging two branches (using the -j)?

  • Is the CVS tag, branch, or date aware?
  • Does it just do a plain text diff (for example, using the unix diff tool)?
  • Does it use a 2 way or 3 way diff?
  • If it uses a 3 way diff, what is the base version it uses?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

还给你自由 2024-08-11 07:19:03

记得前一阵子读到CVS merge其实是使用diff3算法来进行合并的。

此 PDF 文章 对 Diff3 的正式调查,作者:Sanjeev Khanna、Keshav Kunal ,以及宾夕法尼亚大学的 Benjamin C. Pierce 详细描述了 diff3 算法。

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

回答您的问题:

标签、日期意识

来自 CVS 手册页:

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

2 或 3 方式中,并且文本/二进制感知

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

来自 diff3 手册页:

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

比较期间的基本版本

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

然后(引自文章)它:

...取 O 所在的区域
不同于 A 或 B 并且
合并重叠的部分,
导致交替序列
稳定(所有副本相同)和
不稳定(一个或两个副本
改变)块如图1(c).3所示
最后,它检查发生了什么变化
在每个块中并决定改变什么
可以传播,如图
1(d)——这里,第二个块被改变
仅在 A 中(通过插入 4, 5),所以这
变化可以传播到 B,但是
第四块的 A 和 A 都有变化
B,所以没有任何东西可以传播。

I remember a reading a while ago that CVS merge actually uses the diff3 algorithm to perform merging.

This PDF article A Formal Investigation of Diff3, by Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce from the Universtiy of Pennsylvania describes the diff3 algorithm in detail.

If focuses primarily on the properties of the merging algorithm itself, not on how it integrates with CVS.

In answer to your questions:

Tag, date awareness

From the CVS man page:

-j tag[:date] Merge in changes from revisions specified by tag or, when
date is specified and tag is a branch
tag, the version from the branch tag
as it existed on date

2 or 3 way and text/binary awareness

diff3 defaults to a plain text diff. It compares (diffs) 3 versions of the file.

From the diff3 man page:

If `diff3' thinks that any of the
files it is comparing is binary (a
non-text file), it normally reports an
error, because such comparisons are
usually not useful. As with 'diff',
you can force 'diff3' to consider all
files to be text files and compare
them line by line by using the '-a' or
'--text' options.

Base version during comparison

The base version, according to the linked article, is the last common version (O) between the two current versions of the file (A and B). It first uses the 2 way diff algorithm to find the longest common subsequences between O and A, and O and B.

Then (quoted from the article) it:

... takes the regions where O
differs from either A or B and
coalesces the ones that overlap,
leading to the alternating sequence of
stable (all replicas equal) and
unstable (one or both replicas
changed) chunks shown in Figure 1(c).3
Finally, it examines what has changed
in each chunk and decides what changes
can be propagated, as shown in Figure
1(d)—here, the second chunk is changed
only in A (by inserting 4, 5), so this
change can be propagated to B, but the
fourth chunk has changes in both A and
B, so nothing can be propagated.

傾旎 2024-08-11 07:19:03

您可以使用两种不同形式的“合并”命令,它们执行的操作略有不同:

  1. cvs up -j TAG
  2. cvs up -j TAG1 -j TAG2

区别变体之间是选择“基本”修订版的方式,但任一变体的基本算法是,对于每个文件,CVS 选择的两个修订版之间的差异将应用到当前工作副本之上。

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

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

There are two different forms of the "merge" command you can use, that do subtly different things:

  1. cvs up -j TAG
  2. cvs up -j TAG1 -j TAG2

The difference between the variants is how the "base" revision is selected, but the basic algorithm of either variant is that for each file, a diff between two revisions selected by CVS is applied on top of your current working copy.

In the first form, the merge base is the common ancestor of the given TAG and the working copy revision. So let's say your local revision is 1.38 (rev #38 on HEAD) and you're merging 1.34.4.2 (rev. 2 on branch 4 of rev #34 on HEAD) - the common ancestor will be 1.34. I believe this variant does a 3-way merge using the two diffs 1.34..1.38 and 1.34..1.34.4.2, producing conflicts where they mismatch.

In the second form, you're specifying the base revision yourself, so the end result is about the same as cvs diff -r TAG1 -r TAG2 | patch except for getting conflict markers from CVS.

茶花眉 2024-08-11 07:19:03

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

The CVS uses three revisions of file merging the differences between the two into the third. The actual merge doesn't use any information besides the three files checked out. You can see the details in CVS source code. The function in question is RCS_merge in src/rcscmds.c, which uses call_diff3 from diff/diff3.c (or something like that). You can, of course, satisfy your curiosity by looking up CVS sources yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文