git diff 如何判断一行是否已被修改或添加?

How does git diff tell if a line has been modified or added?

给定两个文件,git diff 或任何 diff 工具如何判断添加、修改或删除了哪些行?

是否存在无法识别已编辑行的正确状态的极端情况?

编辑:这个问题更关心差异如何发生的实际方法

git 保留 repo 中每个文件的当前提交版本。如果修改了文件,则会生成提交的版本并将其与文件的当前版本进行比较。这与在硬盘驱动器上区分两个文件是一样的。如果 diff 工具可以比较两个普通文件,那么它可以比较 git 生成的版本和您拥有的版本。

除非存在一些非常隐蔽的错误,否则 diff 工具应该能够捕捉到任何差异,因为 diff 工具会逐行比较两个文件。

Git 存储快照:给定您选择的任意两个快照,Git 提取您想要比较的文件1 到一个临时区域2 然后 运行s a "diff engine" 在两个文件上。该引擎的结果是,或者应该是一系列指令,应用这些指令后,会将左侧文件转换为右侧文件。

Git 有几个内置的 diff 引擎,Git 调用:

  • myers:这使用 algorithm by Eugene W Myers with some slight modifications. There are numerous Whosebug questions and answers about Myers diff: ; Diff Algorithm? (multiple answers but several about Myers diff);

  • minimal:与 myers 相同,但没有进行一些修改以在分而治之的划分部分开始表现不佳时运行得更快而不是更小由于非常长的编辑脚本。从某种意义上说,这才是真正的Myers算法。

  • patience:Bram Cohen 算法;查看 Where can I find the diff algorithm?

  • 的已接受答案
  • histogram:对 patience 的修改,旨在避免意外同步诸如仅大括号行之类的内容。

它还可以 运行 您选择的外部差异引擎。


1或者至少,它想要比较的那些。如果您正在比较实际上不在提交中的文件,它们可能已经被提取。

2Git 主要是在内存中执行此操作,但是当 运行 使用外部差异时,确实会使用临时文件。