GIT,工作目录是如何填充的

GIT,工作目录是如何填充的,git,algorithm,version-control,tree,Git,Algorithm,Version Control,Tree,我想知道GIT工作目录“工作树”是如何填充的 文件是否以某种方式通过树状关系推断出来,这种关系存在于HEAD所指的提交开始,并“向后”指向树的根 也许如果有人能提供某种类型的高层次流程。。即 1.)将头引用的提交中包含的所有文件添加到工作树中 2.)递归地,对于HEAD的父提交引用的每个文件,也将这些文件添加到工作树中 我很好奇这是如何工作的,是否存在一种类似git checkout的详细模式,其中一个名为build_working_tree()的假设函数将输出其操作?暂时忽略repo创建文件树

我想知道GIT工作目录“工作树”是如何填充的

文件是否以某种方式通过树状关系推断出来,这种关系存在于HEAD所指的提交开始,并“向后”指向树的根

也许如果有人能提供某种类型的高层次流程。。即

1.)将头引用的提交中包含的所有文件添加到工作树中

2.)递归地,对于HEAD的父提交引用的每个文件,也将这些文件添加到工作树中


我很好奇这是如何工作的,是否存在一种类似git checkout的详细模式,其中一个名为build_working_tree()的假设函数将输出其操作?

暂时忽略repo创建文件树并指向单个文件的确切方式。让我们坚持一个事实,他们确实创建了对这些对象的引用。重要的一点是,如果对象完全相同(包括文件夹中有完全相同的文件夹和文件),那么git在将来的提交中将只指向相同的对象

假设commit
c1
有一个初始提交,只有
file1.txt

c1 -> file1
然后提交
c2
,它具有相同的
file1
,因此它只是为该对象创建一个对旧对象的引用(与
c1
所做的对象相同)。它还将文件夹
dir1
file2
添加到
dir1
中,以便创建指向这些文件夹的链接

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在评论中给出的链接中概述了这些命令:。这将向您展示如何将提交散列跟踪到repo中存储的对象中,并在每个对象中显示文本-指向每个对象的散列,以及实际对象本身。

无需向后执行提交来填充工作树。请参阅,在最低级别,工作树作为更新索引的副作用而更新:
git checkout
git read tree-u
等效,但更为用户友好。有关详细信息,请参阅.LightCC,您说过“关键是,要为c3重新创建工作目录,您不需要了解c1、c2甚至dir1的任何信息。它指向file1、dir1*、file2和file3,"----你是说c3直接或间接地通过c2指向file1、dir1等?直接。存储在
c3
中的目录树哈希将只包含
file1
dir1*
,然后
dir1*
中的哈希将包含
file2
file3
指针。提交本身还指向父提交(如果有),但这只是日志历史信息,它不使用它来查找任何文件/目录。