当工作目录干净时, git 暂存区包含什么?

What does the git staging area contain when the working directory is clean?

暂存区是否包含上次提交内容的快照? 还是别的?


如果git status显示:

On branch master
nothing to commit, working directory clean

然后如果我发出 git diff --cached

所以 HEAD 与什么相比?

先决条件阅读Read about Git objects, particularly trees and blobs, first.

简短回答:索引始终包含 HEAD 中文件的 blob 的 ID,以及一堆用于跟踪文件更改的标志。它包含最后一次提交的快照,也不是树对象(下面的例外)。

The really long answer can be read here.

稍长的答案:索引(.git/index)总是存储 HEAD 中所有文件的 blob ID 和文件路径的列表,以及关于文件的元数据(权限、修改时间、所有者等...)。

索引还可以包含预先计算的 tree objects (how Git stores directories) 以加速提交。它还存储有关冲突的信息。

因此,"empty" 索引包含所有文件路径的列表、它们的 blob ID、有关文件的元信息,以及 space 用于存储冲突信息。因为它只存储 blob ID(160 位),所以索引避免了与 HEAD 的冗余。对于像 Perl 和 Git.

这样的大型项目,我项目的索引文件从不到 1K 到 500K 不等。

您可以使用 Perl 中的 libgit2 which has wrappers in many programming languages, for example Git::Raw 查看索引。

工作目录是否干净与暂存区包含的内容没有任何关系。暂存区包含为提交而暂存的内容(例如 git add)。是的,任何 尚未 暂存的文件将处于与 HEAD 相同的状态,除非你做了一些奇怪的事情。 git diff --cached是将暂存区的内容与HEAD进行比较(也可以称为git diff --staged)。由于 git commit 将暂存区的内容转换为提交,git diff --staged 显示如果您现在提交将提交的内容。

由于您的 git status 输出显示 "Nothing to commit",它已经告诉您没有分阶段更改,git diff --staged 应该什么都不报告。