Git Internals

工作区、暂存区与对象库

理解 working tree、index 和 object database 这三层,是看懂 add、commit、restore、reset 的关键前提。

适合谁看
  • 想建立稳定 Git 心智模型的学习者
  • 经常遇到历史、引用、恢复问题的开发者
前置知识
  • 会看基础命令输出
  • 知道提交、分支、HEAD 这些名词
常见风险
  • 只背底层术语却不连接到实际命令
  • 把对象、引用、工作区混成一层理解

Git 的许多困惑都来自把这三层混在一起:

  • 工作区:你正在编辑的文件
  • 暂存区:下一次提交准备写入的快照
  • 对象库:已经被 Git 固化下来的对象
工作区、暂存区与对象库大多数 Git 命令之所以让人混乱,不是因为语法复杂,而是因为它们分别落在不同层。先看清层次,再看命令,就容易很多。
工作区checkout.tsedited and visible on disk
暂存区next snapshotstaged content for the next commit
对象库blob / tree / commitdurable history recorded by Git

为什么这三层必须分开理解

因为很多命令的区别就在于它们影响哪一层:

  • git add 主要改暂存区
  • git commit 把暂存区内容写进对象库
  • git restore 可以恢复工作区,也可以恢复暂存区
  • git reset 可能移动引用,也可能同步暂存区和工作区

1. 工作区是什么

工作区就是你当前在文件系统里看到、能直接编辑的那些文件。

它的特点是:

  • 最接近日常开发
  • 变化最快
  • 还没有正式进入 Git 历史

所以工作区里的改动很真实,但还不稳定。

2. 暂存区为什么是 Git 的关键设计

很多版本控制系统初学者第一次接触 Git 时,最不适应的就是 index。

但 Git 的强大很大程度上就来自这层:

  • 它让你在 commit 前先组织下一次快照
  • 它让“这次提交到底包含什么”变成一个可明确控制的问题

如果把暂存区理解成“下一次提交候选快照”,很多命令就会自然很多。

3. 对象库是什么

对象库里放的是已经被 Git 固化下来的 blob、tree、commit、tag 等对象。

一旦内容进入对象库,它就开始具备“历史的一部分”这个性质。

这也是为什么:

  • 工作区改了文件,不等于历史变了
  • add 了文件,不等于 commit 完了
  • commit 之后,变化才真正被固定下来

4. 用这三层解释常见命令

git add

把工作区里的某些内容放进暂存区候选快照。

git commit

把暂存区的状态写成对象,并让分支向前移动。

git restore

可以把工作区或暂存区退回到某个参考状态。

git reset

它之所以容易让人害怕,就是因为它可能同时涉及:

  • 引用位置
  • 暂存区状态
  • 工作区状态

5. 为什么 git status 这么重要

因为 git status 本质上就在帮你看这三层之间的差异:

  • 工作区相对暂存区
  • 暂存区相对当前提交

所以每当你搞不清“现在到底改到哪一层了”,最稳的动作往往都是先跑一次 git status

6. 为什么这能帮助你理解 reset 和 restore

很多人害怕 resetrestore,并不是因为命令本身太复杂,而是没把层次看清楚。

一旦你知道:

  • 哪个操作影响工作区
  • 哪个操作影响暂存区
  • 哪个操作只是移动引用

这些命令的风险边界就不再那么模糊。

一个最稳的理解方式

把暂存区看成“下一次提交的候选快照”,而不是“临时文件堆”。这样 add、commit、reset 的行为就会直观很多。

常见误区

add 就是提交

不是。add 只是组织下一次提交候选内容。

工作区改了就等于 Git 已经保存了

不是。工作区内容还没进入历史。

暂存区只是多余中间层

恰恰相反,正是这层让 Git 的提交边界控制变得非常强。

一个最值得记住的结论

工作区负责“你现在在改什么”,暂存区负责“你准备提交什么”,对象库负责“Git 已经正式记住什么”。