发布于 2026-01-05 0 阅读
0

Git 内部架构 🏛 初始化仓库 暂存文件 提交 分支

Git 内部架构🏛

初始化仓库

暂存文件

提交

分支

Git 为解决复杂问题提供了一个极其简洁优雅的方案。我认为,为了充分理解它的简洁性和强大功能,我们必须了解其背后的工作原理和工程决策。

Git 如何存储文件?运行各种 Git 命令时会发生什么?所有组件之间是如何关联的?它使用的数据结构是什么?

我们将回答以下所有问题👇

初始化仓库

当你git init在某个目录中运行 Git 时,Git 会创建该.git目录,Git 存储和操作的几乎所有内容都位于该目录中。

Git%20internal%20architecture/git_init.gif

tree .git👆运行该git init命令后的输出

它包含几种不同类型的文件和目录:

  • 配置: .git/config.git/description文件.git/info/exclude主要用于配置本地存储库。
  • 钩子:该 .git/hooks 目录包含可在存储库的某些生命周期事件上运行的脚本。
  • 暂存区:该 .git/index 文件(尚未出现在上面的树状列表中)将为我们的工作目录提供一个暂存区。
  • 对象数据库:该 .git/objects 目录是默认的 Git 对象数据库,其中包含所有内容或指向本地内容的指针。
  • 引用:该 .git/refs 目录是存储本地和远程分支、标签和头部引用指针的默认位置。引用是指向对象的指针,通常为 `Object` tag 或 `  Object` 类型commit。引用在对象数据库之外进行管理,以便随着代码库的演进,引用指向的位置可以发生变化。特殊情况下,引用可以指向其他引用,例如 `Object.references`  HEAD

暂存文件

当我们运行命令时,git add .Git 会将工作目录中的所有更改添加到暂存区,并在.git/objects子目录中创建 blob 文件。

每个对象文件都以一个 40 个字符的 SHA-1 哈希值作为文件名。Git 使用文件名的前两个字符来组织目录中的对象。

Git%20internal%20architecture/git_add_kap.gif

这个 Blob 对象包含文件的内容。所有对象一旦创建便不可更改。对文件进行更改并暂存后,将会创建一个全新的对象。

让我们来验证并检查这个blob文件的内容。当我们运行命令时,

cat .git/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238

并没有得到预期的结果。

实际上,Git 使用zlib压缩每个对象,因此你看到的是压缩后的内容。

要查看文件的实际内容,请使用以下命令git cat-file -p <SHA-1>

Git%20internal%20architecture/git-cat_file.gif

提交

运行该git commit命令会在子目录中创建两个新对象objects。一个是树对象,另一个是提交对象。

Git%20internal%20architecture/git_commit_with_tree_2.gif

树状对象

单个树对象包含一个或多个条目,每个条目都是一个 blob 或子树的 SHA-1 哈希值,并包含其关联的模式、类型和文件名。

Git%20internal%20architecture/Untitled.png

提交对象

提交对象的格式很简单:它指定了项目快照在该点的顶级树、父提交(如果有)、作者/提交者信息和提交消息。

Git%20internal%20architecture/Untitled%201.png

我们常用的提交 ID 是提交对象内容的 SHA-1 哈希值。

Git 使用各种不同类型的对象,将所有内容存储为有向无环图。以下是此时的数据结构示例。

Git%20internal%20architecture/Untitled%202.png

分支

在 Git 中,分支本质上是一个指向某个提交对象的轻量级可移动指针。正因如此,在 Git 中创建新分支的成本很低。

每次提交时,分支指针都会自动向前移动。

Git 如何知道你当前在哪个分支上?它维护着一个名为 HEAD 的特殊指针HEAD。HEAD 就是一个指向分支的特殊指针,也就是你当前正在工作的分支。

当我们运行命令时,git checkout -b <NAME>Git 会在以分支名称命名的目录中创建一个新文件refs/heads。该文件包含指向最新提交的指针。

Git%20internal%20architecture/git_checkout_with_diagram.gif


总之,Git 命令是对数据存储的一种抽象。哈希表、基于文件的键值存储和树形数据结构,这些是 Git 的核心技术。

欢迎随时在推特上联系我

请告诉我你还对哪些建筑深度解析感兴趣。请在下方留言。👇

文章来源:https://dev.to/anuj_bansal_/git-internal-architecture-o1j