为啥 Git Diff/Patch 信息与该补丁的 Github 表示不同?
Posted
技术标签:
【中文标题】为啥 Git Diff/Patch 信息与该补丁的 Github 表示不同?【英文标题】:Why is the Git Diff/Patch info different than the Github representation of that patch?为什么 Git Diff/Patch 信息与该补丁的 Github 表示不同? 【发布时间】:2016-12-05 16:22:45 【问题描述】:当您查看文件的差异时,它会在顶部显示差异信息,然后突出显示下面的更改。
但是,在我查看的每个示例中...Github 突出显示的行号始终与 Git 在 Diff/Patch 信息中指定的行号不同。
例如this commit(注意差异数据显示@@ -362,7 +362,7 @@ def association_instance_set(name, association
,但Github在第365行开始突出显示。)
或者这个:
或者这个:
最后还是这个:
似乎 Github 突出显示的实际行号通常比 Git 指定的补丁/差异数据高 3 行左右。
当我检查他们的 API 时,拉下我在上面突出显示并链接的第一个文件,将它吐出到一个数组中,然后使用 index
在数组中进行行数,我也得到了不同的结果。
差异指定更改的行,即362
,使用我的数组转换方法输出到364
,而不是Github 突出显示的365
。
所以有点不对劲。
这是为什么呢?
【问题讨论】:
您使用哪种语言计算index
?它是否使用从零开始的索引(即第 365 行的索引为 364)?
欧文好点。我正在使用 Ruby,它使用基于零的索引。所以这将解释我的实现和 Github 之间的364
到365
的差异。但是,这仍然不能解释 GH 和 Git 之间的 +3
差异。
git diff
有一个选项 -U<n>
或 --unified=<n>
来定义上下文行。默认 n 为 3。
我不清楚您在这里真正要寻找什么。一些可能的问题是:“为什么要使用 diff 提供任何上下文”、“为什么在提供上下文时它在更改的行的两侧各有 3 行”、“为什么 diffs 首先是面向行的”、“如何是否会突出显示 实际 更改 within 提供未更改上下文的差异”,等等。
【参考方案1】:
这些补丁没有任何问题,它们看起来完全符合它们应有的样子。
Unified diff 为 context 包含 3 行(默认情况下,这通常可以由 diff 提供者更改,如果是 git diff
,则为 -U<n>
或 --unified=<n>
)。
让我们看看你的第一个例子中的 hunk:
@@ -362,7 +362,7 @@
它说 补丁文件 从第 362 行开始,并且 diff 中包含 7 行。如果我们查看差异,我们可以看到它确实从第 362 行开始,有 7 行长。
如果我们更详细地查看差异,我们会看到第 362、363、364 行逐字生成。第 365 行标有 -
(分别为 +
),因为它被删除并重新插入了另一行。这在输出中以红色/绿色突出显示。实际差异文件中 not 的一件事是 GitHub 突出显示该行的哪些部分已更改。这是 GitHub 的自定义增强功能。
然后,接下来三个没有改变的上下文行被逐字显示。
Unified diff 只是提供上下文行并将它们包含在 diff 中,GitHub 也以这种方式显示。
您有 1 行已更改 (365),前后三行用于上下文。总共 7 行包含在 patch/diff 文件中(从 362 开始)。
【讨论】:
哦……好吧……这对我来说更有意义。因此,如果有 2 行被更改,那将看起来像这样:@@ -362,8 + 362,8 @@
?
@marcamillion 是的。【参考方案2】:
它是“关闭三”,因为差异格式在实际发生变化的行之前包含三行。
所以@@ -362,7 +362,7 @@
表示更改发生在第 362 + 3 = 365 行,但代码的相关部分从第 362 行开始。
【讨论】:
我明白你在这里想说什么,但为什么他们不显示该行之前的 3 行?即从359
行显示并包括362
行上的实际更改,就像您期望的那样,就像差异所说的那样?
@marcamillion:“他们”是指 Github 还是补丁文件格式的作者? Github 突出显示相关行(以及任何其他上下文)似乎是合理的,而不会受到 diff 输出的过多限制。如果您在谈论补丁格式,那么这样做可能是有原因的,也可能只是出于历史原因(我不确定)。
@marcamillion 第 362 行没有变化。统一差异包括 3 行上下文。第一个变化是在 365。
@Polygnome 这正是我的观点。来自 git 的实际补丁数据,即@@ -362,7 +362,7 @@ def association_instance_set(name, association)
表示更改从第 362 行开始,发生在 7 行以上(加法和减法)。
@marcamillion 您似乎只是误解了@@ -362,7 +362,7 @@
中的行号所说的内容。这并不意味着更改发生在第 362 行。这意味着 补丁中显示的代码部分从第 362 行开始。正如其他人指出的那样,这部分包括未更改的上下文。【参考方案3】:
GitHub(以及一般的统一差异工具)提供了有关更改的一些上下文 - 上面和下面的三行(如果可用)。与输出一起打印的数字包括上下文行。因此,例如,给定一个由数字 1 到 100(每行一个)组成的文件,当与没有数字 42 的文件进行比较时,上下文显示从第 39 行开始的 7 行(或删除后的 6 行)甚至虽然唯一改变的行是第 42 行。
$ diff -u 100 99
--- 100 2016-07-31 09:31:25.000000000 -0400
+++ 99 2016-07-31 09:31:34.000000000 -0400
@@ -39,7 +39,6 @@
39
40
41
-42
43
44
45
【讨论】:
以上是关于为啥 Git Diff/Patch 信息与该补丁的 Github 表示不同?的主要内容,如果未能解决你的问题,请参考以下文章