diff/patch如何工作以及它们的安全性如何?

cen*_*uro 14 git diff patch lcs levenshtein-distance

关于它们如何工作,我想知道低级工作的东西:

  1. 什么会引发合并冲突?
  2. 工具是否也使用上下文来应用补丁?
  3. 他们如何处理实际上没有修改源代码行为的更改?例如,交换函数定义位置.

关于安全性,事实上,巨大的Linux内核存储库是他们安全的证明.但我想知道以下几点:

  1. 关于用户应该注意的工具是否有任何警告/限制?
  2. 算法是否被证明不会产生错误的结果?
  3. 如果没有,是否有实施/论文提出集成测试,至少证明它们在经验上没有错误?像BrianKorverJamesCoplien这些论文的内容.
  4. 同样,Linux存储库应该足以满足前一点,但我想知道一些更通用的东西.源代码,即使在更改时也不会发生太大变化(特别是因为实现了算法和语法限制),但是安全性是否可以推广到通用文本文件?

编辑

好的人,我正在编辑,因为问题含糊不清,答案没有解决细节问题.

Git/diff/patch详细信息

Git似乎默认使用的统一差异格式基本上输出三个东西:变化,变化周围的上下文以及与上下文相关的行号.这些东西中的每一个可能同时也可能没有同时更改,因此Git基本上必须处理8种可能的情况.

例如,如果在上下文之前添加或删除了行,则行号将不同; 但是如果上下文和更改仍然相同,那么diff可以使用上下文本身来对齐文本并应用补丁(我不知道这是否确实发生).现在,其他案件会发生什么?我想知道Git如何决定自动应用更改以及何时决定发出错误并让用户解决冲突的详细信息.

可靠性

我非常确定Git是完全可靠的,因为它确实具有完整的提交历史并且可以遍历历史.我想要的是一些指向学术研究和有关这方面的参考资料,如果它们存在的话.

仍然有点与这个主题相关,我们知道Git/diff将文件视为通用文本文件并在线上工作.此外,diff使用的LCS算法将生成一个试图最小化变化数量的补丁.

所以这里有一些我想知道的事情:

  1. 为什么使用LCS而不是其他字符串度量算法?
  2. 如果使用LCS,为什么不使用度量​​的修改版本来考虑底层语言的语法方面?
  3. 如果使用考虑到语法方面的这种指标,它们能否带来好处?在这种情况下的好处可能是任何东西,例如,更清洁的"责备日志".

同样,这些可能是一个巨大的主题,欢迎学术文章.

Phi*_*lip 5

什么会引发合并冲突?

让我们看看最简单的git的合并策略,递归,首先:当合并两个分支,比如ab,它们有一个共同的祖先c时,git创建一个补丁,从commit c转到提交ad和a的头部并尝试将该补丁应用于b头部的树.如果补丁失败,那就是合并冲突.

默认情况下,git使用递归策略,即3向合并.一般的想法是相同的:如果链接中描述的3向合并算法失败,因为来自不同分支的两个提交改变了相同的行,那就是合并冲突.

工具是否也使用上下文来应用补丁?

是.如果补丁不适用于存储在diff文件中的确切行号,则补丁会尝试根据上下文找到与原始行相邻的几行.

他们如何处理实际上没有修改源代码行为的更改?例如,交换函数定义位置.

补丁不是智能的,它无法区分这些变化.它将移动的函数视为一对已添加的行和几行已删除的行.如果一个分支上的提交改变了一个函数而另一个分支上的提交移动了未改变的,那么尝试合并将始终给你一个合并冲突.

关于用户应该注意的工具是否有任何警告/限制?

至于补丁和差异:不是.两者都使用自20世纪70年代早期以来一直存在的算法并且非常强大.只要他们不抱怨,你就可以相当肯定他们做了你想要的.

话虽如此:git merge试图自己解决合并冲突.在极少数情况下,事情可能会出错 - 这个页面有一个接近其结尾的例子.

算法是否被证明不会产生错误的结果?如果没有,是否有实施/论文提出集成测试,至少证明它们在经验上没有错误?

在这种情况下,"错误的结果"是一个相当不明确的术语; 我声称它无法证明.经验证明的是,应用由diff a b文件生成的补丁a在任何情况下都会产生文件b.

源代码,即使在更改时也不会发生太大变化(特别是因为实现了算法和语法限制),但是安全性是否可以推广到通用文本文件?

同样,diff/patch/git不区分源代码和其他文本文件.git在通用文本文件上也可以像在源代码上一样工作.

我非常确定Git是完全可靠的,因为它确实具有完整的提交历史并且可以遍历历史.我想要的是一些指向学术研究和有关这方面的参考资料,如果它们存在的话.

在git中提交的是具有元数据的树的快照,而不是相邻版本的差异.修补程序和差异根本不涉及修订遍历.(但是在表面以下一级,git然后在使用增量压缩算法的包文件中组织blob .这里的错误很容易发现,因为git内部使用sha1 sum来识别文件,如果发生错误,总和会改变. )

为什么使用LCS而不是其他字符串度量算法?

git默认使用Myers的算法.原始论文解释了为什么它的工作方式.(这不是纯粹的LCS.)