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

标签 git algorithm version-control tree

我想知道 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

重点是,您不需要了解c1c2,甚至dir1 就可以重新创建工作c3 的目录。它指向file1dir1*file2file3,可以在对象repo中找到它们无需了解其他对象。

当然,还有更多内容,因为有时 Git 只存储文件之间的差异,如果文件很大而差异很小(在其他优化中),但这个高级概念涵盖了基本的想法。

就较低级别的管道命令而言,是的,它们确实存在,并且 Git 在执行任务时实际上会使用它们。 Chris 在他的评论中给出的链接中概述了这些内容:Git Internals: Git Objects .这将向您展示如何将提交散列跟踪到存储在存储库中的对象中,并显示每个对象中的文本 - 指向每个对象的散列和实际对象本身。

关于GIT,工作目录是如何填充的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46508643/

相关文章:

git - git 中如何获取最后一次推送的 ID?

git - 如何打印 git 存储库中每个文件的最后提交信息

algorithm - 找到 >= K 个数据值的最小阈值

version-control - 启动新项目时的源代码管理

windows - 使用SVN,我如何有选择地创建一个补丁文件?

git - shell 脚本如何从外部编辑器获取输入(就像 Git 那样)?

克隆图的算法

java - 创建所有可能的诗歌排列

svn - 源代码管理最佳实践-定期从存储库更新您的工作副本

Git 删除子模块并添加另一个分支