Git如何反映从其对象到文件系统的更改?

时间:2018-08-28 07:18:51

标签: git version-control

我读过Git Internals这本书,并且大部分时间都了解Git如何将事物构造为Blob,树,提交以及分支是指向提交的轻量级指针。

我不太了解的部分是Git如何将这些更改跨分支/提交检出反映到文件系统上。

例如:

请考虑两个文件A.txtB.txt,它们已提交给Commit 1。除了这两个文件之外,文件C.txt也被提交到Commit 2

据我了解,对象图将遵循以下内容:

  1. Commit 1指向Tree 1,它对两个初始文件-BlobABlobB
  2. 具有斑点
  3. Commit 2指向Tree 2,其中有三个文件的blob。 BlobABlobB保持不变,因为它们的内容没有更改,而BlobC也将位于Tree 2下。

现在,如果我目前在Commit 2并结帐到Commit 1,则HEAD现在指向Commit 1,我们可以遍历指示状态的有向图存储库的。现在,文件C.txt不再在文件系统上。

Git如何在每次签出时将对象图的状态反映到文件系统上?

谢谢。

1 个答案:

答案 0 :(得分:2)

Git的大多数工作树动作实际上都是通过 index 控制的。这意味着根本不需要遍历图!

索引的主要作用(至少在合并之外)是充当构建 next 提交对象的位置。这给它提供了许多人喜欢使用的名称,即“临时区域”。在索引中,诸如README.txt之类的文件版本将开始与该文件的HEAD版本相匹配。这两个文件实际上都作为 blob 对象存储在资源库中。

工作树将包含README.txt的可用版本,代表文件的扩展版本。如果您已经建立了这样的过滤,那么它也经过了污点过滤和CRLF调整。如果更改工作树版本并希望提交更改,则必须运行git add README.txt:这会将工作树文件复制回索引,应用任何干净的过滤器并进行CRLF到LF调整。如果启用了这些功能,则在存储库中创建一个新的Blob(如果新文件内容与某些现有内容匹配,则重新使用现有的Blob)并将新的哈希存储到索引中。实际上,这将替换文件的索引副本。

到目前为止还不错,但是当您签出某些提交(例如,由于git checkout master并发出命令git checkout develop时会发生什么?索引在这里扮演第二个角色,即跟踪工作树(即索引)并保持有关工作树的缓存信息。 (这也是其第三个名称​​ cache 的来源。)

Git已将master转换为提交哈希以提取该提交,但在这一点上它再次这样做。此时,Git正在使用git read-tree命令的所谓的两棵树合并模式。它还将develop转换为提交哈希,因此现在有两个提交哈希,分别是master(当前提交)和develop(所需的提交)。在确保这些确实是提交之后, 1 Git将它们转换为树哈希ID:HEAD树以及所需的树或目标树。

同时 index 列出工作树中每个跟踪文件的哈希ID。在理想情况下,对于索引和/或HEAD提交中的每个文件 F F 在两个{{1} }和索引。如果是这样,HEAD的索引副本本身就是“干净的”(匹配)。工作树副本可能是干净的,也可能不是干净的(可能匹配索引副本,也可能不匹配)—在大多数情况下,索引作为 cache 的角色有助于使最后一次测试非常快。

对于两者 F 中存在的每个文件 F 的目标哈希F HEAD的{​​{1}}哈希匹配,否则不匹配。对于目标树中没有 但在HEAD中确实存在的文件, F 的索引和工作树副本是干净的,或者不是。如果文件是干净的,则可以安全地删除两个副本(如果文件不在目标文件中)或用目标树中的版本替换两个副本(如果文件在目标文件中)。但是,如果目标树的哈希值匹配 F哈希值,则根本不需要触摸索引和工作树条目,因此Git不需要。

简而言之,只有HEAD和目标树不匹配的地方,Git才需要更改工作树中的任何内容以实现检出。如果不匹配的部分是文件HEADHEAD中但不在目标中,则目标变为删除xyz.txt -但仅允许这样做如果它是“干净的”,除非您将HEAD添加到xyz.txt中。如果不匹配的部分是文件既不在--force也不在索引中,而不在在目标中,则目标变为创建 {{ 1}}中包含目标的内容,但是只有在文件不存在或者文件在ignore指令中列出时,才允许这样做。 2


必须使用

1 分支名称来始终标识提交哈希。 (允许使用标签名称来标识其他类型的对象。)因此,从理论上讲,无需进行检查。 Git是否真的检查,取决于代码路径。

2 最后一部分有时会引起一些严重的疼痛。 Git确实应该(但不应)区分“忽略此文件,因为它很容易重新创建”和“忽略此文件,因为它不应该提交,但是永远不要破坏它”,因为它包含一些珍贵的东西例如用户配置数据。”