git *.cpp 文件的差异在一个存储库中不打印任何内容

git diff for *.cpp files prints nothing in one repository

一旦命令 git diff *.cpp 停止在一个存储库中打印任何内容,尽管 git diff *.h 工作正常。 git diff 适用于 *.cpp 文件。

它会是什么?

所以我在存储库根目录中有一个 .cpp 文件,所以 git diff *.cpp 现在只打印这个文件的更改,而 git diff '*.cpp' 对子目录中的所有文件都可以正常工作。

修复要注意运行,例如:

git diff '*.cpp'

或:

git diff \*.cpp

或更正式地说:

git diff -- '*.cpp'

或类似。

这是怎么回事?

问题中遗漏了:所需的输出是 subdir/subfile.cpp 的差异,但工作树的顶层包含一个名为 file.cpp 或类似文件的文件。

问题源于您使用的是 Unix/Linux-style shell,它扩展了 * 和其他通配符或 glob 字符 before 运行ning 您在命令行输入的命令。但这里也有一些微妙之处。

因为当前目录下存在一个名为file.cpp的文件,当你运行:

git diff *.cpp

shell*.cpp 替换为名称以 .cpp 结尾的所有文件的名称,因此 运行s:

git diff file.cpp

Git 然后尽职尽责地为一个名为 file.cpp 的文件生成 diff——或者在这种情况下,no diff 因为没有区别。

当顶层目录中没有 没有 个名为 file.cppzorg.cpp 或类似文件的文件时,此 shell 只是调用git 带有参数 diff*.cpp,就像您引用了星号一样。这给了 Git 扩展 *.cpp 参数的机会,当 Git 扩展它时,它这样做的方式不同于 shell.

为什么要使用--

git diff命令有多个选项,例如-s-p-w--name-status--name-only、等等。

根据您拥有的文件,假设您需要当前目录中名为 -z 的文件的差异列表。如果你那么 运行:

git diff -z

Git 认为您的意思是提供 -z 选项 ,而不是获取名为 -z 的文件的差异列表。如果您想要 -z* 等的差异,也会出现类似的问题。

通常,您可以使用文件名 ./-z 而不是 -z 来解决此问题。因为 ./-z 不是以 - 开头的,所以 Git 并没有被误认为是一个选项。但这个问题更普遍,在其他情况下(其他命令)也会出现。例如,假设您有一个名为 develop 文件 并且您 运行:

git checkout develop

Git 会认为您的意思是查看名为 develop.

分支

所有 Git 命令接受 -- 作为 分隔符 ,通常意味着 没有更多选项:此点之后的任何内容都是改为参数 。对于 git diff-- 之后的任何内容都被视为 pathspec,其中包括进行 glob 扩展,前提是 glob 字符超过了 shell。

这就是the SYNOPSIS section of the git diff documentation中语法描述的意思:

git diff [<options>] [<commit>] [--] [<path>...]
git diff [<options>] --cached [<commit>] [--] [<path>...]
git diff [<options>] <commit> <commit> [--] [<path>...]
git diff [<options>] <blob> <blob>
git diff [<options>] --no-index [--] <path> <path>

方括号表示有些东西是可选的,所以所有的选项都是可选的。尖括号表示某些参数应该替换为满足括号内类型要求的字符串。文字 -- 或其他文字选项意味着您应该按文字键入这些字符——例如 git diff --cached 需要文字字符串 --cached。最后,... 表示 "repeat the previous as often as you like"。

由于文字字符串 -- 是可选的,因此您不必输入它 — 但如果您输入, 之后的所有内容都必须采用 a 的形式<path>。这种形式非常通用:几乎任何字符都是有效的。不过,该文档缺少对 pathspec 定义的交叉引用(这里可能应该使用 <pathspec>,而不仅仅是 <path>)。 pathspecs 的完整描述在 the gitglossary.