代表 Git 存储库的数学结构是什么

2024-05-15

我正在学习 Git,如果我能描述一下代表 Git 存储库的数学结构,那就太好了。例如:它是一个有向无环图;它的节点代表提交;它的节点有代表分支等的标签(每个节点最多一个标签,没有标签使用两次)。(我知道这个描述不正确,我只是想解释我正在寻找的内容。)


除了 Nevik Rehnel 评论中的链接(根据请求复制到此处:eagain.net/articles/git-for-computer-scientists http://eagain.net/articles/git-for-computer-scientists and gitolite.com/gcs http://gitolite.com/gcs), and sehe 的观点是提交图形成 Merkle 树 https://stackoverflow.com/a/18589734/1256452,我会添加一些注释。

  • 对象存储中有四种对象类型:提交、树、注释标签和 blob(文件)。
  • 提交对象恰好包含一个树引用(当然可以指向更多树)、父 SHA-1 哈希值的可能为空的列表(必须全部是更多提交)、作者(姓名、电子邮件和时间戳) 、提交者(与作者的形式相同)和提交文本。
  • 树对象包含重复 0 次或多次的(模式、子对象、文件名)列表。如果子对象是另一棵树,则文件名代表一个目录。如果它是一个 blob,则代表一个文件。该模式看起来像 POSIX 文件模式,如果是120000(符号链接的文件模式),文件的“内容”实际上是符号链接目标。某些模式值(ab)用于子模块,但我忘记了是哪个。 R 和 W 模式位不被存储,只存储 X 位(即使如此,如果存储库配置说忽略它们,它们也会被忽略)。
  • 带注释的标签对象包含对象引用、标记器(名称、电子邮件和时间戳)和标签文本。引用的对象通常是提交,但标记对象可以指向任何对象(甚至另一个标记对象)。
  • 标签(分支、标签和引用日志等)位于对象存储之外。对于带注释的标签,外部有一个标签,指向对象存储内的带注释的标签对象。对于轻量级标签,外部标签直接指向提交。
  • 没有限制只能有一个 root 提交。任何没有父母的提交都是根。
  • Git 几乎从不创建一个空树(这代表一个空目录),除了两种情况:每个存储库中始终有一个空树,并且如果您进行初始空提交(使用git commit --allow-empty)它使用那棵空树。 (由于空树没有子对象,它的 SHA-1 哈希值是一个常量 https://stackoverflow.com/q/9765453/1256452.)
  • “DAG”描述通常是指通过关闭提交父哈希而形成的树。但是,树对象通常不应将自身包含在其任何子树中,并且如果您设法创建循环树结构,您将无法检查它(因为它无限递归)。假设你不能创建具有相同校验和的两棵不同的树(如果可以的话,你会破坏 git),你将找不到包含树 T1 的树 T1,而树 T2 包含校验和为 T1 的不同树。因此,树也隐式地是一个 DAG,并且附加到提交 DAG,它们形成了一个更大的 DAG。 :-)
  • 对象存储中未引用的对象将被垃圾收集git gc。空树似乎不受收集影响。任何东西都在refs/ and logs/目录和文件packed-refs (in .git,或者对于裸仓库或者当$GIT_DIR被设置,无论其他地方)作为参考,特殊名称(HEAD, ORIG_HEAD, ETC。);我不确定是否有其他随机文件,如果创建于.git并包含有效的 SHA-1,可以作为参考,也可以不作为参考。
  • 该索引有一些我从未研究过的格式。它包含对对象存储中的对象的引用。当你git add一个文件,git 将文件放入对象存储中,并将(非文本)SHA-1 哈希值放入索引文件中。这些是防止垃圾收集的有效引用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代表 Git 存储库的数学结构是什么 的相关文章

随机推荐