Git 内部:它是如何工作的以及 .git 文件夹的作用

发布: (2026年1月14日 GMT+8 14:09)
4 分钟阅读
原文: Dev.to

Source: Dev.to

引言

对许多开发者来说,Git 像是一段神奇的咒语。我们输入 git add .,随后 git commit -m "fixed stuff",推送到远程服务器,并祈祷一切顺利。它运行时,简直太棒;一旦出错,就像在蒙着眼睛拆弹一样令人焦虑。

了解表面之下的工作原理可以把盲目的记忆转化为真正的掌握。Git 不仅仅是一堆命令;它是一个精心设计的信息管理系统。通过剥开层层包装,我们可以构建出 Git 实际“思考”方式的心智模型。

.git 文件夹

仓库的隐藏核心是 .git 文件夹。它通常在文件资源管理器中被隐藏,因为手动更改可能会损坏仓库。

  • 工作目录.git 之外的所有内容;你编辑文件的沙盒。
  • .git 文件夹 – 存储每个文件的每个版本、完整提交历史以及所有分支的数据库。

重要提示: 删除 .git 文件夹会抹掉整个项目历史,只留下磁盘上当前可见的文件。

关键子目录和文件

路径描述
objects/存放所有文件内容和历史(数据库的核心)。
refs/保存指针(引用),如分支(heads/)和标签。
HEAD一个纯文本文件,指示当前所在的分支。

Git 的工作方式类似键值存储。是由内容生成的 40 位 SHA‑1 哈希。内容的任何改动都会产生完全不同的哈希,从而保证数据完整性。

Git 的数据模型

对象类型

Git 在 objects/ 中存储三种主要对象:

Blob

  • 包含文件的原始内容。
  • 存储文件名或其位置。
  • 不同文件中相同的内容会对应同一个共享的 Blob。

Tree

  • 表示一个目录。
  • 包含指向 Blob(文件)和其他 Tree(子目录)的条目,以及它们的文件名。

Commit

  • 将所有内容组合成一次快照。
  • 包含:
    • 指向顶层 Tree 的指针(当时项目根目录的快照)。
    • 元数据:作者、时间戳和提交信息。
    • 指向父 Commit 的指针(前一次快照)。

理解这些对象有助于阐明 暂存区(也称 Index)的作用。

暂存区(Index)

Index 记录哪些 Blob 应该被包含在下一个快照中。

添加文件 (git add)

git add style.css

运行 git add 时:

  1. Git 将文件内容压缩为一个 Blob。
  2. 计算该 Blob 的 SHA‑1 哈希并将 Blob 存入 .git/objects/
  3. 更新 Index,使 style.css 映射到该 Blob 哈希,表明该文件应成为下次提交的一部分。

创建提交 (git commit)

git commit -m "Added Styles"

运行 git commit 时:

  1. Git 创建一个 Tree 对象,反映当前目录结构,使用 Index 中记录的 Blob 哈希。
  2. 创建一个 Commit 对象,指向该 Tree 并指向前一个 Commit。
  3. 将当前分支引用(例如 refs/heads/main)移动到新的 Commit 哈希。

通过将工作目录 → Blob → Tree → Commit 的流程可视化,你可以清晰地看到 Git 如何记录历史,以及为什么 git addgit commit 会表现出如此行为。

Back to Blog

相关文章

阅读更多 »

什么是 git?

为什么你需要 Git 对于许多开发者来说,U 盘只是一个存放和检索旧项目或文件的地方。但当你拥有太多文件夹、冗余文件……