为啥 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 之间的364365 的差异。但是,这仍然不能解释 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 表示不同?的主要内容,如果未能解决你的问题,请参考以下文章

diff patch 命令制作补丁

几个重要的shell命令:diff patch tar find grep

比较文件 diff patch

Git diff patch 怎么弄?

Linux命令diff、patch

linux Development Tools 包括哪些软件