09 — .git 地图:打开那个隐藏文件夹

09 --- .git 地图:打开那个隐藏文件夹

摘要: 本章深入探索 Git 仓库的核心------.git 隐藏文件夹。通过可视化地图和动手实验,你将了解 .git 目录结构及各文件/文件夹的作用,理解 Git 如何将版本历史、分支、暂存区等状态存储为普通文件。重点掌握 objects/(存储历史内容)、refs/(存储分支/标签引用)、HEAD(当前分支指针)、index(暂存区)和 logs/(操作日志)等核心组件的功能。通过观察 add、commit 等命令对 .git 文件的实际影响,你将不再视 Git 为黑盒,并为后续深入学习对象模型和引用机制打下坚实基础。

写在前面:这一章要解决什么

前面八章你用了无数 git 命令,但那个藏着历史的 .git 文件夹从来没打开过。这一章就带你 打开它看看------

  • .git 里都有什么
  • 每个文件夹/文件是干嘛的
  • 为什么说「Git 像 Linux,一切皆文件」
  • 你每次 add、commit 到底动了哪些文件

学完后,你应该能:

  1. 说清 .git 下主要路径的职责
  2. 不再觉得 Git 是黑盒
  3. 为后面的「对象、引用」章节打基础

读者设定: 大一同学,会用基本 Git,但没看过 .git 内部。


1. 定位:为什么要看 .git

1.1 一句话先记住

Git 不神秘------它的状态大多就是 .git 里的普通文件。

像 Linux 把一切都当文件(连设备都是 /dev/xxx),Git 也把历史、分支、当前在哪 都存在文件里。

1.2 看了 .git 能得到什么

不看 看了
Git 是黑盒 知道每次命令动了什么文件
出错靠瞎试 能从文件层面排查
觉得分支很玄 分支就是个文本文件,存一个哈希
怕改坏历史 知道 .git 备份好就行

1.3 和你已经会的对比

你已经会的 .git 对应
浏览器书签是个文件 分支是 .git/refs/heads/名字
「当前打开的标签页」存在配置 HEAD 文件说你在哪
数据库的数据文件 objects/ 存历史内容

1.4 本章内容目标

目标 你能做到
看地图 说出主要路径职责
不慌 知道 Git 状态是文件
备份 知道备份什么能保住历史
预告 为对象(第 10 章)、引用(第 12 章)铺垫

2. 本质:.git 是 Git 的大脑

2.1 先看一张总图

图:命令作用于四个层------对象库、引用、暂存区、工作区。本章重点在 .git 内的前三层。

2.2 用白话拆开

.git 是 Git 仓库的「大脑」。删了它,仓库就退化成普通文件夹。它里面主要有:

路径 干什么
objects/ 存历史内容(文件快照、目录树、提交)
refs/ 存「名字」(分支、标签、远程跟踪分支)
HEAD 说「你现在在哪条分支」
index 暂存区(第 02 章那个「篮子」)
logs/ 引用移动的日志(reflog 的数据源)
config 本仓库的配置
hooks/ 钩子脚本(默认是样例)
info/exclude 本地忽略规则(不提交)

2.3 几条硬规矩

规矩 白话
删 .git = 丢历史 工作区文件可能还在,但历史没了
别手改 refs 和 objects 不懂哈希前容易搞乱
index 是二进制 用 git ls-files --stage 看,别用编辑器打开
备份 .git 约等于备份历史 工作区文件是派生的

2.4 新手最常踩的坑

坑 表现 办法
以为历史在工作区文件里 删了 .git 才发现历史没了 备份要带 .git
手改分支文件 引用和日志不同步 用 git branch 等命令
以为 .git 不能动 不敢看 看可以,改要小心
把 .git 提交进另一个仓库 嵌套混乱 .git 不该被跟踪

3. 建议学习顺序

text 复制代码
先看 `.git` 长啥样
  → 认主要路径
  → 做一次 add + commit,看哪些文件变了
  →(预告)下一章拆 objects

4. 动手准备

bash 复制代码
mkdir lab-dotgit
cd lab-dotgit
git init -b main
git config user.name "Ada Example"
git config user.email "ada@example.com"
git --version
text 复制代码
git version 2.43.0

5. 跟着做:看 .git 里有什么

5.1 刚 init 完的地图

bash 复制代码
find .git -maxdepth 2 | sort | head -30
text 复制代码
.git
.git/HEAD
.git/branches
.git/config
.git/description
.git/hooks
.git/info
.git/info/exclude
.git/objects
.git/objects/info
.git/objects/pack
.git/refs
.git/refs/heads
.git/refs/tags

白话翻译: 刚 init 完,objects/ 基本是空的,refs/heads/ 也是空的(还没有任何提交)。

5.2 看 HEAD:你现在在哪

bash 复制代码
cat .git/HEAD
text 复制代码
ref: refs/heads/main

白话翻译: HEAD 是个文本文件,内容是「我指向 refs/heads/main 这条分支」。main 文件还没建(没提交),但 HEAD 已经准备好指它。

5.3 做一次 add,看什么变了

bash 复制代码
printf 'hello\n' > f.txt
git add f.txt
find .git/objects -type f
text 复制代码
.git/objects/58/7be6b4c3f93f93c489c0111bba5596147a26cb

白话翻译: add 把文件内容写成「对象」塞进 objects/。这个长串是内容的哈希(第 10 章细讲)。

5.4 做一次 commit,再看什么变了

bash 复制代码
git commit -m "c1"
find .git/objects -type f
text 复制代码
.git/objects/49/97ca7a42e3ad9b729fbad3acd44fbabd07b6bd
.git/objects/58/7be6b4c3f93f93c489c0111bba5596147a26cb
.git/objects/aa/204d311bcd992bb9ea23ca4a795cfa8cce4275

白话翻译: 多了两个对象:一个是「目录树」(说 f.txt 叫这个名字、内容是哪个哈希),一个是「提交」(指向那棵树 + 作者 + 说明)。

5.5 看分支文件

bash 复制代码
cat .git/refs/heads/main
text 复制代码
aa204d311bcd992bb9ea23ca4a795cfa8cce4275

白话翻译: 分支 main 就是个文本文件,存的是最新提交的哈希。所谓「分支」就是这一行字。

5.6 看 logs:reflog 的数据源

bash 复制代码
cat .git/logs/HEAD
text 复制代码
0000000000000000000000000000000000000000 aa204d311bcd992bb9ea23ca4a795cfa8cce4275 Ada Example <ada@example.com> 1784883528 +0800	commit (initial): c1

白话翻译: logs/HEAD 记录了 HEAD 的移动历史。这就是 git reflog 显示的东西(进阶章细讲)。

图:再看一遍------add/commit/switch 各动了哪些层。


6. .git 主要路径速查

路径 干什么 谁来改
objects/ 存历史内容(对象) add、commit、fetch
refs/heads/ 本地分支(每条一个文件) commit、branch、reset
refs/tags/ 标签 tag
refs/remotes/ 远程跟踪分支 fetch
HEAD 当前在哪 switch、checkout
index 暂存区 add、reset
logs/ 引用移动日志 大部分命令
config 本仓库配置 git config --local
hooks/ 钩子脚本 手动启用
info/exclude 本地忽略 手动编辑

7. 对照表:降低记忆负担

7.1 命令 → 大致动了哪些 .git 文件

命令 objects refs index 工作区 logs
add 写 blob --- 改 --- ---
commit 写 tree + commit 改分支 刷新 --- 写
branch 名字 --- 新建分支文件 --- --- 有时
switch --- 改 HEAD 改 改 写
reset --hard --- 改分支 改 改 写
fetch 下载 改远程跟踪 --- --- 写
tag 可能写 tag 对象 新建标签文件 --- --- ---

完整表见第 11 章。

7.2 「.git 里有啥」vs「工作区有啥」

.git 里有 工作区里有
历史 有(objects + refs) 没有
你正编辑的文件 没有 有
暂存区 有(index) 没有
配置 有(config) 没有

8. 安全习惯

8.1 建议这样做

习惯 原因
备份带上 .git 没它就没历史
看可以,改要小心 用 Git 命令改,别手编辑
别把 .git 提交进别的仓库 嵌套混乱
学会用 git 命令查 git status、git log、git ls-files

8.2 别这样做

别 原因
手改 refs/heads/ 文件 容易和 logs 不同步
用编辑器开 index 二进制,会搞坏
删 objects/ 里的文件 历史就缺了
把 .git 当普通文件夹提交 嵌套仓库

9. 真实场景

9.1 仓库「坏了」怎么排查

  • git status 报奇怪错误 → 先看 .git/HEAD 是否还在
  • 分支不见了 → 看 .git/refs/heads/ 还有没有
  • 历史少了 → git fsck 检查对象完整性(进阶)

9.2 换电脑迁移项目

  • 整个项目目录(含 .git)拷过去,历史就在
  • 或者只拷工作区 → 没历史,等于重新开始

9.3 想看但不敢改

  • 用 cat、find、ls 只读查看
  • 真要实验,先复制一份再玩

10. 稍微多懂一点点(可选)

  1. logs/ 是 reflog 的来源 :git reflog 读的就是这里的文件。
  2. ORIG_HEAD:危险操作前 Git 会备份一份旧 HEAD 位置。
  3. FETCH_HEAD :上次 fetch 拉来的远端 tip。
  4. MERGE_HEAD:合并进行中时存在,记录「对方」是谁。
  5. objects/pack/ :很多对象压缩打包放这(gc 维护)。

11. 小实验(请一定动手)

实验甲:看 init 后的地图

  1. 建仓,find .git -maxdepth 2 | sort。
  2. cat .git/HEAD,看指向哪。
  3. 确认 objects/ 和 refs/heads/ 基本空。

实验乙:看 add + commit 后的变化

  1. 建文件、add、find .git/objects -type f。
  2. commit 后再 find .git/objects -type f,数多了几个。
  3. cat .git/refs/heads/main 看分支存的哈希。
  4. cat .git/logs/HEAD 看移动记录。

实验丙:建个分支看文件

  1. git branch dev。
  2. ls .git/refs/heads/,应该多了 dev。
  3. cat .git/refs/heads/dev,和 main 一样吗?

通过标准: 能说清「分支是文件、HEAD 是文件、历史在 objects」。


12. 常见问题

问 1:.git 能删吗?

能删,但历史就没了。工作区文件可能还在。

问 2:.git 能拷给别人吗?

能,整目录拷过去就是完整历史。但更推荐用 clone。

问 3:objects 里那串是什么?

是内容的哈希。第 10 章细讲。

问 4:分支文件能手改吗?

能改但不推荐。用 git branch 等命令,避免和 logs 不同步。

问 5:index 能用编辑器打开吗?

别。它是二进制。用 git ls-files --stage 看。

问 6:HEAD 和分支啥关系?

HEAD 通常是个符号引用,指向当前分支;分支文件又指向提交。

问 7:logs/ 和 reflog 一样吗?

reflog 读的就是 logs/。进阶章细讲。

问 8:.git 多大算正常?

看历史大小。小项目几 KB 到几 MB;大型项目可能上百 MB(用 gc 维护)。


13. 总结、学习路线与思维升华

13.1 这一章请记住的

点 记住什么
.git 是大脑 删了就丢历史
objects 存历史内容
refs 存名字(分支、标签)
HEAD 说你在哪
index 暂存区
logs reflog 数据源
下一章 拆 objects 看对象类型

13.2 在整个系列中的位置

text 复制代码
01--08 新手篇
09 .git 地图          ← 当前
10 对象模型
11 操作→文件
12 引用与 HEAD
13 暂存区深入
14 历史是图
15--24 进阶

13.3 思维升华

Git 不神秘------它的状态大多是 .git 里的普通文件。

看懂地图,命令就不再是黑盒。

备份带上 .git,历史就跟着你走。

13.4 参考资料

命令输出样例验证环境:Git 2.43.0 ;演示作者信息为虚构:Ada Example <ada@example.com>。

13.5 本章检查清单

  • 看过 .git 目录结构
  • 说清 objects/refs/HEAD/index 各干什么
  • 看过 add 后多了对象
  • 看过 commit 后多了对象 + 分支文件
  • 看过 .git/refs/heads/main 存哈希
  • 知道备份要带 .git
  • 不手改 refs/objects

打开 .git,Git 就不再是黑盒了。下一章我们拆 objects/,看里面那四类对象到底长啥样。

相关推荐
派小心.2 分钟前
多端数据分析平台的漏斗可以跨端搭建吗?5 步搭出跨端转化漏斗
大数据·运维·服务器·前端·数据分析
vx_Biye_Design4 分钟前
springboot旅游管理系统18006-计算机课程设计、毕业设计
java·spring boot·后端·python·elasticsearch·django·课程设计
见闻小天地10 分钟前
数据中心柴发出口保护怎么选?Emax 与 Tmax XT 的定位与分工
大数据·运维·人工智能·业界资讯
anxiao_m13 分钟前
跨地域大文件怎么传?2026主流传输软件实测对比
大数据·数据库·文件传输
cc57250265335 分钟前
2027 届秋招|大数据 / 统计类专业面物流运营,履约效率的表达框架
大数据
newsxun1 小时前
校园餐全链条管理有了“实操手册” ——《学校食品安全与营养健康管理操作指南》在成都发布
大数据·人工智能
Madison-No76 小时前
Git版本控制工具(一)
git
ly76899 小时前
倒排索引与 FST 在 Lucene 中的内存布局:segment、docValues 与词典压缩的工程取舍
elasticsearch·lucene·倒排索引·doc values·fst
奈落2410 小时前
AI 编程从助手到 Agent:基于两份资料看哪些环节可以交出去,哪些必须自己攥住
大数据·人工智能
Joker可视化开发平台10 小时前
AI短剧接棒真人剧:开机量跌七成,普通人进场窗口在收窄
大数据·人工智能