为什么 git diff 不显示有关特定提交和文件的信息?

Why git diff doesn't show information on a specific commit and file?

我对文件 source.json 进行了更改,删除了一行。我提交了更改(其他文件也已更改)。然后我又做了一次提交。

现在我想查看我使用 git diffsource.json 所做的更改。

我做的是:

git diff HEAD^^ -- path/to/source.json

虽然我没有得到任何输出(命令的退出状态为 0)。如果我输入 git diff HEAD^^,我会看到更改 source.json 以及所有其他已更改的文件。

这是git diff-tree --no-commit-id --name-only -r HEAD^的输出:

path/to/AboutUs.js
path/to/Contact.js
path/to/source.json

这是git diff HEAD^^的输出:

diff --git a/path/to/source.json b/path/to/source.json
index 3ba32e950..d86eb9c25 100644
--- a/path/to/source.json
+++ b/path/to/source.json
@@ -565,7 +565,6 @@
-  "someContent": "someContent",
   "someContent2": "someContent2",

有什么我遗漏的吗?

虽然 git diff 确实 允许路径规范将其输出限制为与路径规范匹配的文件,但有时有点令人惊讶的是这些路径规范是相对于 工作树中的当前位置

换句话说,如果:

git diff-tree --no-commit-id --name-only -r HEAD^

产生:

path/to/AboutUs.js
path/to/Contact.js
path/to/source.json

并且您处于工作树的顶层,然后执行:

cd path/to

您将需要使用:

git diff HEAD^^ -- source.json

因为最后一个参数实际上意味着 ./source.json

或者,在:

之后
git rev-parse --show-cdup

打印 ../.. 你可以这样做:

git -C ../.. diff HEAD^^ -- path/to/source.json

因为 -C 将那个 git diff 命令暂时上移了两个级别。 (我在脚本和别名中使用了这种通用模式,例如,

git -C "$(git rev-parse --show-cdup)" ls-files --other --exclude-standard

在一些 shell 代码中检测未跟踪的文件。)


Git 这里并不完全一致。如果您希望在此子目录中查看提交 HEAD^^ 中的 source.json 版本,您必须 运行:

git show HEAD^^:./source.json

如:

git show HEAD^^:filename

指的是存储库顶层中名为 filename 的文件——即使您仍在 path/to 中。 git show 的诀窍是在提交说明符之后提供的文件名 而不是 路径规范参数。但是 do 采用路径规范的其他 Git 命令实际上可能假设 :(toplevel).

有关路径规范的更多信息,请参阅 the gitglossary