Git存储库内部格式解释

本文关键字:格式 解释 内部 存储 Git | 更新日期: 2023-09-27 18:15:56

是否有关于Git如何在其存储库中存储文件的文档?我试着在网上搜索,但没有可用的结果。也许我使用了不正确的查询,或者这是一个伟大的秘密- Git存储库内部格式?

让我解释一下,为什么我需要这些火箭科学信息:我正在使用c#来获取文件历史记录的存储库。但是在libgit2sharp库中,它目前没有实现。所以(作为一个负责人;)我需要自己实现这个功能,并为社区做贡献。

但是在将内核源代码移动到github之后,我甚至不知道从哪里开始搜索。

提前感谢!

Git存储库内部格式解释

存储库的内部格式非常简单。Git本质上是一个内容可寻址的用户空间文件系统。

这是一个缩略草图。

Git将其内部数据结构存储为对象。有四种对象:blob(有点像文件)、树(有点像目录)、提交(在特定时间点的文件系统快照以及如何到达那里的信息)和标记(用于标记重要提交的指针)。

如果您查看存储库的.git目录,您会发现objects目录包含以SHA-1哈希命名的文件。每一个都代表一个对象。您可以使用plumbing git cat-file命令检查它们。一个来自我的存储库的提交对象示例

noufal@sanitarium% git cat-file -p 7347addd901afc7d237a3e9c9512c9b0d05c6cf7
tree c45d8922787a3f801c0253b1644ef6933d79fd4a
parent 4ee56fbe52912d3b21b3577b4a82849045e9ff3f
author Noufal Ibrahim <noufal@..> 1322165467 +0530
committer Noufal Ibrahim <noufal@..> 1322165467 +0530
Added a .md extension to README

你也可以在.git/objects/73/47addd901afc7d237a3e9c9512c9b0d05c6cf7看到对象本身。

您可以像这样检查其他对象。每个提交都指向一个树,表示那个时间点的文件系统,并且有一个(在合并提交的情况下有多个)父节点。

对象作为单个文件存储在objects目录中。这些被称为松散物体。当您运行git gc时,不再能够到达的对象将被修剪,剩余的对象将被打包到一个文件中并进行增量压缩。这样空间效率更高,并且压缩了存储库。在运行gc之后,您可以查看.git/objects/pack/目录以查看git包文件。要解压缩它们,可以使用管道命令git unpack-objects命令。.git/objects/info/packs文件包含当前存在的包文件列表。

引用

你需要知道的下一件事是什么是引用。这些是指向某些提交或对象的指针。你的分支和其他类似的东西是作为引用实现的。有两种"真实的"(类似于文件系统中的硬链接)和"符号的"(类似于符号链接的指向真实引用的指针)。

位于.git/refs目录中。例如,在上面的存储库中,我位于master分支上。我最近的提交是

noufal@sanitarium% git log -1
commit 7347addd901afc7d237a3e9c9512c9b0d05c6cf7
Author: Noufal Ibrahim <noufal@...>
Date:   Fri Nov 25 01:41:07 2011 +0530
    Added a .md extension to README

你可以看到我的master引用位于.git/refs/heads/master指向这个提交。

noufal@sanitarium% more .git/refs/heads/master
7347addd901afc7d237a3e9c9512c9b0d05c6cf7

当前分支存储在位于.git/HEAD的符号引用HEAD中。在这里

noufal@sanitarium% more .git/HEAD
ref: refs/heads/master

如果你切换分支,它会改变。

整个存储库仅使用提交的DAG(每个提交都指向代表某个时间点的文件的树)和指向DAG上的各种提交的引用来管理,以便您可以操作它们。

进一步阅读

  • 我在这里的git培训中有一个演示,解释了其中的一些内容。
  • 在http://book.git-scm.com/的社区书中有一些关于内部的部分。
  • Scott Chacon的Pro Git书有一个关于内部的部分
  • 他还有一个关于内部的窥视码PDF。