如何理解diff输出的统一格式?

如何理解diff输出的统一格式?

diffutils 手册

接下来是一个或多个差异;每个块都显示文件不同的一个区域。统一格式的帅哥看起来像这样:

@@ from-file-line-numbers to-file-line-numbers @@
line-from-either-file
line-from-either-file...

如果一个大块只包含一行,仅显示其起始行号。 否则它的行号看起来像“开始,计数”。空块被认为是从块后面的线开始。

如果一个块及其上下文包含两行或多行,它的行号看起来像“开始,计数”。否则仅显示其结束行号。空块被认为在该块之前的行处结束。

他们的意思是什么?您能否也举一些例子来说明它们的含义?

特别是,我无法区分最后两段中的情况之间的差异。他们似乎在谈论相同的案件,但我怀疑他们没有。

  • 第一段中的“如果”情况和第二段中的“否则”情况有什么区别?

  • 第一段中的“否则”情况和第二段中的“如果”情况有什么区别?

答案1

我怀疑第一段(您突出显示的两段中)试图解释,from-file-line-numbers而第二段则试图解释to-file-line-numbers

我将忽略晦涩难懂的文本,并解释 GNU 如何diff实现统一diff(解决你的问题的标题)。

diff -u <(printf "a\nb\nc\n") <(printf "a\n")

产生以下结果:

--- /proc/self/fd/11    2018-11-08 11:16:09.183611033 +0100
+++ /proc/self/fd/12    2018-11-08 11:16:09.184611029 +0100
@@ -1,3 +1 @@
 a
-b
-c

(我将省略后续示例中的前两行,因为它们不需要太多解释。)

这表明我们的两个“文件”不同,只有一组差异(“块”)。在统一补丁中,每个文件比较都是由一对以---(“from”文件)和+++(“to”文件)开头的行引入的。在每个文件比较中,每个块都以一行开头和结尾的行引入@@。该行标识源文件和目标文件中的更改位置。起始位置以 开头-(不是后面数字的一部分),终止位置以 开头+。位置是一对数字:起始行和长度(如果为 1,则省略)。因此,在上面的补丁中,我们进行了一项更改,将 from 文件中从第 1 行开始的三行转换为 to 文件中从第 1 行开始的单行。

帅哥可以包含上下文,就是上面的情况。默认情况下,diff包括三行上下文(如果有);它还会合并上下文重叠的帅哥。如果更改之前和/或之后没有三行上下文,则上下文会减少;因此,上面我们在更改之前只有一行上下文,而在更改之后则没有。此上下文被视为块中给出的更改的一部分,因此它有助于起始行和长度。

diff -u0 <(printf "a\nb\nc\n") <(printf "a\n")

说明了这一点:

@@ -2,2 +1,0 @@
-b
-c

这是相同的更改,但没有上下文:因此它被简化为将从第 2 行开始的两行转换为从第 1 行开始的无行的更改。

最简单的位置对应于更改单行的补丁,没有上下文:

$ diff -u0 <(printf "a\nb\nc\n") <(printf "a\nb\nd\n")
@@ -3 +3 @@
-c
+d

根据上下文,这将是

@@ -1,3 +1,3 @@
 a
 b
-c
+d

(上下文的用处是允许补丁对于与原始文件不完全匹配的“来自”文件仍然有用。patch如果在行号不完全匹配的地方应用“模糊”补丁,如果它在与原始位置有一定距离。)

相关内容