当我运行git diff
时,输出以以下内容开头:
diff --git a/foo/bar b/foo/bar
如果我尝试运行普通的diff --git
,会提示--git
选项不存在(显然,我猜想,对于一个低级工具来说知道特定的DVCS似乎很愚蠢)。在man
页面中也没有提到它。这个选项从哪里来?
当我运行git diff
时,输出以以下内容开头:
diff --git a/foo/bar b/foo/bar
如果我尝试运行普通的diff --git
,会提示--git
选项不存在(显然,我猜想,对于一个低级工具来说知道特定的DVCS似乎很愚蠢)。在man
页面中也没有提到它。这个选项从哪里来?
这是一个"虚拟差异选项",用于向读者表明它不仅仅是运行diff
命令的输出。例如,在git自己的git存储库中:
$ git diff HEAD~1..HEAD | head
diff --git Documentation/git.txt Documentation/git.txt
index bd659c4..7913fc2 100644
--- Documentation/git.txt
+++ Documentation/git.txt
@@ -43,6 +43,11 @@ unreleased) version of Git, that is available from the 'master'
branch of the `git.git` repository.
Documentation for older releases are available here:
+* link:v2.10.0/git.html[documentation for release 2.10]
+
$
如果你使用相同的文件名称两次调用diff
命令,它本身将不会显示任何差异。git
假设会创建与Documentation/git.txt
的两个不同版本相对应的临时文件,并将它们提供给diff
-- 但是这些临时文件的名称并没有用处。我认为git diff
会修改diff
的输出以使其对读者更有意义。(这种推测并不完全正确,请参见下文。)
深入研究git源代码,可以发现diff.c
中硬编码了字符串字面值"diff --git"
:
strbuf_addf(&header, "%s%sdiff --git %s %s%s\n", line_prefix, meta, a_one, b_two, reset);
查看历史记录以找到包含该字符串的最早版本:diff.c
$ git log -n 1 b58f23b3
commit b58f23b38a9a9f28d751311353819d3cdf6a86da
Author: Junio C Hamano <junkio@cox.net>
Date: 2005-05-18 09:10:47 -0700
[PATCH] Fix diff output take #4.
This implements the output format suggested by Linus in
<Pine.LNX.4.58.0505161556260.18337@ppc970.osdl.org>, except the
imaginary diff option is spelled "diff --git" with double dashes as
suggested by Matthias Urlichs.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
$
假设 <Pine.LNX...>
是邮件列表中某封电子邮件的消息ID。无论如何,此提交消息表明 diff --git
是一种“虚拟差异选项”。
这封电子邮件由nos在评论中引用,似乎是导致此事的讨论的一部分。
更新: 我之前猜测 git diff
会编辑 diff
的输出并添加此信息。我刚刚尝试在 strace
下运行 git diff
。它实际上未调用diff
或其他任何命令。相反,所有输出都由git
进程本身打印,并且显然它会在内部计算差异。此行为还可能取决于git
版本(我使用的是2.23.0),可用的 diff
命令以及所使用的参数。
我注意到GNU diff有一个--label = LABEL
选项,可以用于此类操作:
'-L LABEL'
'--label=LABEL'
Use LABEL instead of the file name in the context format (*note
Context Format::) and unified format (*note Unified Format::)
headers. *Note RCS::.
但是git diff
似乎没有使用它,至少在我尝试的一种情况下,并且我在git源代码中也没有看到对它的引用。
git diff
没有使用它,在我尝试过的一个案例中也没有看到在git源代码中对它的引用。--git
表示 diff 是以 "git" 的格式进行的。它并不是 /usr/bin/diff
命令的选项。您可以在diff格式文档列表中找到其他格式包括:
diff --combined
diff --cc
diff --summary
正如Keith所提到的,在GNU diff中(使用diff -v
检查您的版本),您可以通过这样使用--label
来获得类似于Git风格的补丁:
从备份中恢复单个文件
diff -u --label a/path/to/file.ext --label b/path/to/file.ext path/to/file.ext~ path/to/file.ext
command_that_outputs_previous_version | diff -u --label a/path/to/file.ext --label b/path/to/file.ext - path/to/file.ext
find
等。当比较的一侧不存在时,例如新文件,请与/dev/null
进行比较。
osx
标签来表示这是 macOS 附带的diff
工具,而 GNU 工具可能会有所不同。 - JHZ