Git 是全世界程序员每天都要按几十次的"保存按钮",但绝大多数人——包括很多资深工程师——从未真正看过它的内核。我们记住了 add、commit、push、pull、merge、rebase 这一串咒语,遇到冲突就复制粘贴 Stack Overflow,却说不清一次 commit 到底存了什么、一个分支到底是个什么东西。Tech With Nikola 的这支 16 分钟视频,干脆剥掉 Git 的 GUI 和 CLI 外衣,直接带你钻进 .git 目录,看那座由 SHA-1 哈希一层层堆叠起来的内容寻址森林。
它解决的不是"怎么用 Git",而是"Git 凭什么这样设计"。看完你会忽然打通很多点:为什么创建分支快得像没有成本、为什么 commit 根本不是 diff、为什么 Linus Torvalds 在 man page 里把 Git 称作 "stupid content tracker"(愚蠢的内容追踪器)。这其实不只是一堂工具科普,更是一堂关于"如何用极简原语造出超强系统"的架构课。
| 项目 | 内容 |
|---|---|
| 视频标题 | How GIT works under the HOOD? |
| 频道 | Tech With Nikola |
| 时长 | 16 分 01 秒 |
| 播放量 | 约 25 万次(截至 2026 年) |
| 核心主题 | Git 底层对象模型:blob / tree / commit、内容寻址、分支即指针 |
Tech With Nikola 是计算机科学深度讲解领域的标杆频道之一,风格是"少废话、多白板、直击底层"。这支视频是它被引用最多的代表作之一,因为它把 Git 那套看似魔法的行为还原成了一组可以亲手触摸的对象。
视频开篇就抛出 Linus 的那句名言,并强调这绝非自嘲。Git 的内核不是"记录文件的历史变更",而是一个 key-value 数据库:key 是内容的 SHA-1 哈希,value 是内容本身。你往 Git 里塞的任何东西——一个文件、一棵目录树、一次提交——都会先算出一个 160 位哈希(显示成 40 个十六进制字符),作为它在 .git/objects 里的唯一地址。Git 根本不在乎这个文件叫什么名字、这是第几次改,它只在乎"这段内容的指纹是什么"。
延伸分析:这一句"内容即地址"是理解 Git 所有反直觉行为的钥匙。因为地址由内容决定,所以内容相同必然地址相同(自动去重);因为地址由内容决定,所以任何篡改都会让哈希失效(完整性自校验)。更深远的是,这套思想 Git 在 2005 年就用上了,而它正是后来区块链的哈希链、IPFS 的内容寻址、Docker 镜像分层的共同基因。Git 不是一个工具,它是一种"用哈希组织数据"的设计范式。
视频把 Git 的世界压缩成三类对象。blob 存文件内容——注意,只有内容,没有文件名、没有时间戳、没有权限。tree 存目录结构,它本质上是一张表:列出"这个名字的文件、是这个权限、指向那个 blob 的哈希;这个子目录、指向那个 tree 的哈希"。commit 存一次提交的元数据:作者、时间、提交信息,以及最关键的两个指针——一个指向根目录 tree 的哈希,一个或多个指向父 commit 的哈希。
视频最有价值的演示,是用 git cat-file -p <hash> 命令层层展开这些对象:从一个 commit 的哈希出发,找到根 tree,再递归展开子 tree,最后在叶子节点找到 blob、打印出文件内容——整个过程就是在遍历一棵哈希树。
延伸分析:三种对象的精妙在于分工正交——内容(blob)、结构(tree)、历史(commit)三者分离。于是同一个文件内容出现在多个目录、多个提交里时,物理上只存一份 blob;目录结构可以被复用;而历史是一条不可变的哈希链。这种"关注点分离"是 Git 既快又省空间的根本原因。
这是整支视频最颠覆认知的一击。大量教程和直觉都把 Git 描述成"记录每次改了什么",仿佛每次 commit 存的是一个 diff(差异补丁)。这是错的。Git 的 commit 存的是那一刻整个项目树的完整快照。
你改了一个文件里的一个字符,Git 不会只存那一行的差异,而是:为修改后的文件内容算出新的 blob 哈希,构建一棵新的 tree(其中没改动的文件依然指向旧的 blob 哈希),再用这棵新 tree 创建新 commit。每次 commit 都是一张全景照片,而不是一张标红圈的批改图。
延伸分析:这个设计看似"浪费",恰恰是 Git 速度和可靠性的来源。读取任何一个历史版本都不需要像 SVN 那样从起点回放一长串 diff,而是直接跳到那个 commit 的根 tree,几乎 O(1) 还原。而未改动的文件自动复用旧 blob(内容寻址的去重红利),实际存储开销远小于直觉。后来 Git 在 packfile 里又对相似 blob 做 delta 压缩,把"快照模型"的语义和"delta 存储"的体积一举两得。
commit 指向 tree,tree 指向子 tree 和 blob,每一层的哈希都由下一层内容算出来——这是一棵典型的 Merkle 树(哈希树)。视频点明:正是这种结构让 Git 拥有 cryptographic integrity。
任何人在任何层级篡改哪怕一个 bit——改内容、改文件名、改提交信息——都会改变该对象的哈希,进而改变引用它的父对象哈希,层层向上传导,最终改变 commit 哈希。你无法悄悄改历史而不被发现:被篡改的 commit,其哈希必然对不上下游引用。
延伸分析:这就是为什么 Git 对数据损坏几乎免疫。
git fsck能遍历整棵对象图,揪出任何"游离"或"损坏"的对象。这套机制和区块链、ZFS、BitTorrent 的 piece hashing 同源——都是用哈希把数据组织成一棵自校验的树。理解了这一点,你就会明白为什么说"Git 的历史是不可被静默篡改的"。
视频的另一记重锤是 Git 的分支几乎免费。为什么创建分支这么快、为什么一个项目能轻松挂着几百个分支?因为 Git 的分支根本不是"复制一份代码",而是 .git/refs/heads/<分支名> 下的一个文本文件,里面只写着这个分支当前指向的 commit 的那 40 个十六进制字符。
创建分支 = 写一个 40 字符的文件;切换分支 = 移动一个指针;合并分支 = 移动指针或创建一个有两个父 commit 的新 commit。 对比之下,SVN 创建分支要复制整棵目录树(O(n)),Git 是 O(1)。HEAD 是一个特殊引用,通常指向一个分支(如 refs/heads/main)而不是直接指向 commit,这让"当前在哪个分支"成为一等概念。
延伸分析:Linus 多次说过,Git 真正的创新不是"分布式",而是"它的分支模型"。正是"分支即指针"让 feature 分支、release 分支、topic 分支可以随意创建和丢弃,gitflow、trunk-based 这些工作流才成为可能。你之所以敢一天开五个分支,是因为在底层,它们加起来不过是五个 40 字符的文件。
.git/index 是 Git 最被误解的部分。视频澄清了三个空间的区别:工作区(working directory,你看到的文件)、暂存区(staging area / index)、仓库(repository,.git 里的对象库)。
git add 把工作区的变更"暂存"到 index——index 本质上是你"下一次 commit 将要拍的那张快照"的草稿。git commit 时,Git 根据 index 的内容构建一棵 tree,再用它创建 commit。
延伸分析:这个"中间层"看似多余,却是 Git 灵活性的核心。它让你能从一堆杂乱的改动里挑出一部分进入本次提交(
git add -p逐块暂存),把逻辑相关的变更组织成干净、原子化的提交历史。大量新手觉得 Git 难,正是因为忽略了"暂存区"这第三层空间,把工作区当仓库直接提交,于是提交历史一团乱麻。理解 index,你才算真正会用 Git。
视频收尾点出了内容寻址架构带来的几项"免费"红利。第一是自动去重:相同内容(哪怕跨文件、跨版本)产生相同 blob 哈希,物理上只存一份。第二是不可变历史:已创建的对象永不修改,所谓"改历史"本质是创建新对象并移动引用,旧对象仍能被 git reflog 找回——这正是"误删在 Git 里常常能救回来"的根本原因。第三是 packfile:松散对象会定期被打包,packfile 里对内容相似的 blob 做 delta 压缩,存"相对于 base 的差异",在保持快照语义的同时实现接近 delta 存储的压缩率。
延伸分析:这套设计的代价是
.git目录里会有大量小对象与 packfile,但换来的是分布式协作的天然支持——两个仓库只要交换对象(按哈希寻址、天然去重、哈希即校验),就能可靠同步,完全不需要中心仲裁。这也是为什么 Git 能在断网、离线、多人并发的情况下依然正确:它的同步协议本就是"我有这些哈希,你有那些哈希,我们补齐彼此没有的"。
flowchart TD
CORE["Git 本质:内容寻址的键值存储<br/>Key = SHA-1(40 个十六进制字符)<br/>Value = 对象"]
CORE --> C["commit 对象<br/>= 根 tree 哈希 + 父 commit + 元数据<br/>(一次完整快照,而非 diff)"]
C --> T["tree 对象<br/>= 目录表<br/>(文件名 + 权限 + 子哈希)"]
T --> B["blob 对象<br/>= 纯文件内容<br/>(无文件名 / 无时间)"]
T --> T2["子 tree 对象<br/>(嵌套目录)"]
T2 --> B
C -. parent .-> C
B -. "相同内容 → 相同哈希<br/>→ 自动去重" .-> B
C --> R["引用 refs<br/>refs/heads/main = 40 字符 SHA<br/>(分支 = 一个指针文件)"]
R --> H["HEAD<br/>→ 指向当前分支"]
IDX["暂存区 index<br/>= 下一次快照的草稿<br/>(git add 写入)"] -->|"git commit 构建新 tree"| T
style C fill:#fde68a,stroke:#92400e,stroke-width:2px
style R fill:#bfdbfe,stroke:#1e3a8a,stroke-width:2px
style IDX fill:#bbf7d0,stroke:#14532d,stroke-width:2px
style CORE fill:#fecaca,stroke:#7f1d1d,stroke-width:2px
第一,从此告别 Git 恐惧症。 当你明白 commit 是快照、分支是指针、index 是草稿,那些让新手崩溃的命令就全成了直观操作。rebase 不是黑魔法,它只是把一串 commit 重新接到另一个基点之上,本质是创建新 commit + 移动分支指针;reset 是移动 HEAD/分支指针;cherry-pick 是把某个 commit 的改动"复刻"成新 commit。它们都在玩同一套"对象 + 引用"的把戏。
第二,学会用底层命令 debug。 卡住时直接钻进 .git:git cat-file -p <hash> 查看任何对象的原始内容,git log --graph --oneline 看哈希链,git reflog 看引用移动的历史(这是你的后悔药),git fsck 检查对象完整性。当你能亲手把一个 commit 展开成 tree 再展开成 blob,Git 就再没有秘密了。
第三,架构层面的偷师。 Git 是"用最简原语造出最复杂系统"的教科书。内容寻址 + 不可变对象 + 可变引用这三件套,不仅造出了版本控制,也是区块链、IPFS、Docker 镜像层、ZFS 的设计根基。任何需要"去中心化、可校验、可同步"的系统,都能从 Git 这套架构里学到东西。
第四,工作流建议。 基于"分支几乎免费"——大胆使用短生命周期的 feature 分支;基于"index 是草稿"——养成用 git add -p 组织原子提交的习惯,让每次 commit 都是一个独立的逻辑变更;基于"对象不可变 + reflog"——知道绝大多数误操作都能挽回,不必对 Git 过度恐惧。
git cat-file -t <一个 commit 哈希> 和 git cat-file -p <哈希>,亲手展开 blob/tree/commit,这比看十遍视频都深刻。Git 不是版本控制工具,而是一座由 SHA-1 哈希堆叠起来的内容寻址森林——commit 是快照、分支是指针、index 是草稿,一旦看懂这套极简原语,Git 的所有魔法就都变成了常识。
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
