13

有没有关于 Git 如何在他的存储库中存储文件的文档?我正在尝试通过 Internet 进行搜索,但没有可用的结果。也许我使用了不正确的查询,或者这是一个很大的秘密——Git 存储库内部格式?

让我解释一下,为什么我需要这个火箭科学信息:我正在使用 C# 获取文件历史表单存储库。但在libgit2sharp图书馆中,目前尚未实施。所以(作为一个负责任的人;)我需要自己实现这个功能并为社区做出贡献。

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

提前谢谢了!

4

1 回答 1

42

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

这是一个缩略图。

对象

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

如果您查看.git存储库的目录,您会发现一个objects包含以 SHA-1 哈希命名的文件的目录。它们中的每一个都代表一个对象。您可以使用管道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时,无法再访问的对象将被修剪,其余的将打包到一个文件中并进行 delta 压缩。这更节省空间并压缩存储库。运行 gc 后,您可以查看.git/objects/pack/目录以查看 git packfiles。要解压它们,您可以使用管道命令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

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

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

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

同样,标签也是这样的引用(但它们不像分支那样不可移动)。

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

进一步阅读

于 2011-11-25T09:34:56.903 回答