在Git中,一个空提交是否有一个空树?

4

我阅读了Git 内部原理 - Git 对象,对于一些关于树对象的内容还不是很清晰。

例如,当前分支是master。在master上的最终提交对象是一个空提交,并用cmt_end表示。根据git-commit-tree,提交对象只有一个树对象。因此,cmt_end的树对象称为tree_end

我的困惑是:

  • git-commit记录存储库中的更改。这是否意味着tree_end包含了cmt_end和其父级之间的差异?如果是这样,由于cmt_end是一个空提交,tree_end应该是一个空树。如果不是这样,那么为空提交使用空树是否可以?
  • git-commit--allow-empty选项表示一个空提交与其唯一的父提交具有完全相同的树。这是否意味着提交的树对象记录整个工作目录,而不是使用git-commit时所做的更改?

1
请注意,提交的树实际上是由 git write-tree 构建的,它使用索引(而不是工作区)来构建树对象。您可以运行 git ls-files --stage 查看索引的内容。 - torek
2个回答

4

树对象记录整个工作目录,提交对象记录树对象和其他条目,例如作者姓名、提交日期和提交消息,可以在 git log -1 <commit> --pretty=rawgit cat-file -p <commit> 看到。

--allow-empty 指示 git commit 创建一个重用其父级的树对象的提交对象。如果新提交是没有任何父提交的根提交,则树对象是一个特殊的空树,其 SHA-1 值为 4b825dc642cb6eb9a060e54bf8d69288fbee4904。空树映射到一个空目录,其中没有子目录或文件。在 --allow-empty 中的 "empty" 表示自上次提交或初始状态以来没有进行更改。

当空提交有一个父提交时,它的树与父提交相同。树可能是空树或非空树,具体取决于父提交引用的树。当空提交没有父提交时,其树始终为一个空树。


你有文档支持树形对象记录整个工作目录的说法吗? - Hobin C.
@HobinC。https://git-scm.com/book/zh/v2/Git-Internals-Git-Objects 和 https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftreeobjectatreeobject。严格来说,树对象记录的是一个目录,而不总是整个工作目录。它可能是工作目录的子目录。但整个工作目录始终由树对象记录,该对象由提交对象引用。 - ElpieKay

1
正如你最后猜测的那样,提交中的树对象实际上代表的是该点上存储库的内容,而不是相对于上一次提交所做的更改。当提交为空时,这意味着该提交相对于上一次提交没有更改,但这并不意味着该提交时存储库不包含任何文件。空提交的树对象将与上一个提交的树对象相同。

你有支持这些陈述的文档吗?还是我错过了上面提供的一些要点? - Hobin C.
@HobinC。我不知道文档中具体描述在哪里,但我会查一下看看。 - David Z

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接