.git 文件夹里有什么?

发布: (2026年1月10日 GMT+8 04:36)
8 min read
原文: Dev.to

Source: Dev.to

Source:

介绍

在本文中,我们将打开引擎盖,看看驱动 Git 的 .git 文件夹
阅读完本文后,你将了解:

  • Git 如何在内部存储文件并跟踪历史。
  • 提交是如何在内部构建的。

在深入十六进制的兔子洞之前,请确保你已经掌握了以下内容:

  • 基本的 Git 命令git addgit commitgit push
  • 命令行 – 使用 cd 导航,使用 ls 列出文件等。
  • 好奇心 – 愿意探索抽象概念。

新手使用 Git?

如果你需要复习基础知识,请查看:

  • 轻松学 Git:版本控制入门指南

.git 文件夹

如果你在电脑上打开任意 Git 仓库并启用“显示隐藏文件”,就会看到一个名为 .git 的文件夹。

  • 它不仅仅是一个配置文件夹——它是一个 数据库
  • 它是仓库的 大脑、心脏和灵魂
  • 删除项目文件 但保留 .git 文件夹,就可以恢复所有内容。
  • 删除 .git 文件夹会把仓库变成普通的文本文件夹,所有历史记录都会丢失。

Git 本质上是一个 内容可寻址文件系统——换句话说,它是一个 键值存储

核心 Git 对象

对象存储内容用途
Blob原始文件内容(例如 main.ts)。Git 会压缩内容并以 blob 形式存储。保存数据,但没有文件名。
Tree目录结构。将文件名(例如 main.ts)映射到 blob ID,并且可以包含其他树(子目录)。重建文件夹层次结构。
Commit某一时刻的仓库快照。包含指向一个 tree 的指针、元数据(作者、日期、提交信息)以及指向父提交的指针。将所有内容关联在一起,形成历史链。

简而言之

  • Blob – 文件数据。
  • Tree – 文件夹组织结构。
  • Commit – 快照(谁、何时、为何)。

SHA‑1(及 SHA‑256)哈希

您可能已经看到过类似 a1b2c3d… 的长字符串。它们是 SHA‑1 哈希——通过对对象内容应用数学公式生成的 40 字符标识。

  • SHA = 安全散列算法(Secure Hash Algorithm)。
  • 更新的 Git 版本也支持 SHA‑256,但 SHA‑1 仍是默认,因为整个生态系统(GitHub、GitLab、各种工具)仍然依赖它。

检查仓库使用的哈希算法

git rev-parse --show-object-format
# Output: sha1   (or sha256)
  • rev-parse – 一个底层命令,用于解析和处理 Git 引用。
  • --show-object-format – 显示仓库使用的对象哈希格式。

从编辑器到仓库

步骤 1 – git add .

发生了什么:

  1. Git 读取每个已修改文件的内容。
  2. 为这些内容创建 blob 对象 并将其存放在 .git/objects 中。
  3. 更新 索引(暂存区)——一个列表,记录“在下次提交时,这个文件名指向这个 blob 哈希”。

步骤 2 – git commit -m "Message"

发生了什么:

  1. 树对象创建 – Git 遍历索引,构建表示当前文件夹结构的树对象。
  2. 提交对象创建 – 创建一个提交对象,指向顶层树以及前一次提交(即它的父提交)。
  3. HEAD 更新HEAD 指针(当前分支标签)被移动到新的提交 ID。

完整性魔法

  • 文件的哈希值(例如,"Hello World")始终保持不变。
  • 更改内容(例如,"Hello Worlds")会产生完全不同的哈希值。
  • Git 不仅对内容进行哈希,还包括对象类型大小,从而保证唯一性和完整性。

由于每个提交都会存储其父提交的哈希,整个历史形成了一个密码学链——对任何对象进行篡改都会导致链断裂。

HEAD 文件

HEAD 是一个小型文本文件,用来告诉 Git 你当前所在的工作位置。典型内容:

ref: refs/heads/main
  • 这表示“我们位于 main 分支”。
  • 执行 git checkout dark-mode 只会将 HEAD 更新为 ref: refs/heads/dark-mode

.git 目录内部

目录 / 文件用途
objects/存储所有 Git 对象(blobs、trees、commits、tags),文件名为它们的 SHA‑1 哈希。
refs/书签目录——分支和标签。
refs/heads/每个分支的文件(例如 feature-login)。每个文件包含一个 40 字符的提交哈希。
HEAD指向当前分支(或在分离的 HEAD 状态下直接指向某个提交)。
index二进制暂存区。由 git add 更新;保存时间戳、文件名和准备在下次提交时使用的 blob 哈希。

检查对象

对象以压缩的二进制形式存储,因此使用 git cat-file 打开它们:

git cat-file -p <object-id>
# -p = pretty‑print(人类可读)

提交对象的示例输出

tree 8d3a1...
parent 1f4e2...
author Satpal Rana 1703865000 +0000

Created the homepage hero section

摘要

  • .git 文件夹是一个功能完整的数据库,存放 blobstreescommitsreferences
  • Git 的内容可寻址存储使用 SHA‑1(或可选的 SHA‑256)哈希来保证完整性。
  • 添加文件会创建 blobs 并更新 index;提交时会构建 trees 和提交对象,然后移动 HEAD
  • 分支是指向提交哈希的轻量指针,使得创建和切换分支非常快速。

现在,你可以清晰地看到每次运行 Git 命令时在 内部 发生了什么。祝你探索愉快!

动手实践 Git

仓库配置

此文本文件包含特定于此仓库的配置,例如:

  • 远程仓库的 URL(origin)。
  • 本地用户覆盖设置。
  • 分支跟踪信息。

创建新仓库

git init demo
cd demo

创建文件并提交

echo "Hello Git" > hello.txt
git add .
git commit -m "First commit"

探索对象

# List the objects stored in the repository
ls .git/objects

# Show the contents of a specific object (replace <sha> with an actual SHA‑1)
git cat-file -p <sha>

观察 Git 如何在内部存储和检索数据。

结论

在本文中,我们探讨了 Git 如何使用 blobstreescommitshashes 在内部存储数据。理解这些后,Git 就不再显得神秘,而是更可预测。

“隐藏的文件夹有时藏着最大的秘密。”
匿名开发者

Back to Blog

相关文章

阅读更多 »

第1周作业

Git 是一种用于代码协作、跟踪代码更改及其作者的版本控制系统。常用的 Git 命令 bash git --version 检查是否…