我需要编写一个简单的源代码控制系统,并想知道我将使用哪种算法来实现文件差异?
由于许可证问题,我不想查看现有的源代码。我需要在MPL下获得许可,因此我无法查看任何现有系统,如CVS或Mercurial,因为它们都是GPL许可。
为了给出一些背景知识,我只需要一些非常简单的功能 - 文件夹中的二进制文件。没有子文件夹,每个文件的行为都像它自己的存储库。除了某些权限外没有元数据。
整体上非常简单的东西,我唯一担心的是如何只存储文件从修订版到修订版的差异,而不会浪费太多空间但也没有太低效(也许存储每个X更改的完整版本,有点像视频中的关键帧?)
答案 0 :(得分:6)
Patience Diff是一个很好的算法,用于查找两个可能对人有意义的文件之间的增量。这通常比天真的“最长公共子序列”算法提供更好的结果,但结果是主观的。
话虽如此,许多现代版本控制系统在每个阶段都存储完整的文件,并在以后仅在需要时计算实际差异。对于二进制文件(可能不是非常可压缩的),您可能会发现存储反向增量可能最终会更有效。
答案 1 :(得分:5)
最长公共子序列算法是类似diff的工具使用的主要机制,可以被源代码控制系统利用。
“Reverse Deltas”是一种常见的存储方法,因为您主要需要从最新版本开始向后移动。
答案 2 :(得分:5)
查看Subversion的源代码怎么样?它在Apache License 2.0下获得许可
答案 3 :(得分:3)
Gene Myers撰写了一篇好文章An O(ND) Difference Algorithm and its Variations。在比较序列时,迈尔斯就是那个人。您可能还应该阅读Walter Tichy关于RCS的论文;它解释了如何通过存储最新版本和差异来存储一组文件。
答案 4 :(得分:2)
虽然化石是GPL,但delta算法基于rsync并描述了here
答案 5 :(得分:2)
存储增量(前向或后向)的想法在版本控制方面是经典的。问题一直是,“你存储什么三角洲?”
许多源控制系统存储基本上由“diff”计算的增量,例如,最长共同子序列的面向行的补充。但是,您可以以特定于这些文档的方式计算特定类型文档的增量,以获得更小(通常更易理解)的增量。
对于编程语言源代码,可以计算程序结构上的Levenshtein距离。可以在Smart Differencer
找到一套基本上可以用于各种流行编程语言的工具。如果您要存储非文本文件,则可以利用其结构来计算较小的增量。
当然,如果您想要的是最小的实现,那么只需存储每个文件版本的完整图像就很容易了。如果不漂亮,太字节磁盘使该解决方案可行。 (用于隐式执行此操作的PDP10文件系统)。
答案 6 :(得分:1)
前几天我实际上在考虑类似的东西......(奇怪,是吧?)
我没有给你一个很好的答案,但我得出的结论是,如果我要写一个文件差异工具,我会用一个算法(用于查找差异)这样做,其功能有点像REGEXes贪得无厌。
至于存储DIFF ...如果我是你,而不是存储前向DIFF(即你从原始文件开始,然后当你使用版本151时计算机150与它相差),使用存储的DIFF对于您的历史记录,但将您的最新文件存储为完整版本。如果你这样做,那么每当你使用最新文件时(可能是99%的时间),你将获得最佳性能。