我想知道 GIT 工作目录“工作树”是如何填充的?
文件是否以某种方式通过树状关系推断出来,这种关系从 HEAD 引用的提交开始并“向后”工作到树的根部?
也许如果有人可以提供发生的某种类型的高级过程..即
1.) 将 HEAD 引用的提交中包含的所有文件添加到工作树。
2.) 递归地,对于 HEAD 的父提交引用的每个文件,也将它们添加到工作树中。
我很好奇它是如何工作的,是否有像 git checkout 这样的东西的详细模式,其中一个名为 build_working_tree() 的假设函数会输出其操作?
最佳答案
暂时忽略 repo 是如何创建文件树和指向单个文件的。让我们坚持这样一个事实,即它们确实创建了对这些对象的引用。重要的一点是,如果对象完全相同(包括具有完全相同的文件夹和文件夹中完全相同的文件),那么 git 将在未来的提交中指向相同的对象。
假设提交 c1
的初始提交只有 file1.txt
c1 -> file1
然后提交 c2
,它有相同的 file1
,所以它只是创建一个对旧对象的引用(与 c1
做了)。它还在 dir1
中添加了一个文件夹 dir1
和一个 file2
,因此它创建了指向这些文件夹的链接。
c2 ----> dir1 -> file2
\
c1 -> file1
现在添加一个提交 c3
,并且 file1
是相同的,所以 c3
仍然可以指向同一个对象,并且file2
相同,但新的 file3
被添加到 dir1
。这意味着 dir1
必须更改(我将其显示为 dir1*
,但它仍然可以指向旧的 file2
对象。新的 file3
也添加到 dir1*
。
c3 -> dir1* ------> new file3
\ \
c2 -\ -> dir1 -> file2
\
c1 -> file1
重点是,您不需要了解c1
、c2
,甚至dir1
就可以重新创建工作c3
的目录。它指向file1
、dir1*
、file2
和file3
,可以在对象repo中找到它们无需了解其他对象。
当然,还有更多内容,因为有时 Git 只存储文件之间的差异,如果文件很大而差异很小(在其他优化中),但这个高级概念涵盖了基本的想法。
就较低级别的管道命令而言,是的,它们确实存在,并且 Git 在执行任务时实际上会使用它们。 Chris 在他的评论中给出的链接中概述了这些内容:Git Internals: Git Objects .这将向您展示如何将提交散列跟踪到存储在存储库中的对象中,并显示每个对象中的文本 - 指向每个对象的散列和实际对象本身。
关于GIT,工作目录是如何填充的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46508643/