Git Internals

工作区、暂存区与对象库

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

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

数据 / 性能事实

关键引语

The index is a binary file (generally kept in .git/index) that stores information about what is currently going into your next commit.

学完这篇你会掌握什么

  • 理解 工作区、暂存区与对象库 的核心作用和适用场景
  • 掌握 工作区、暂存区与对象库 的基本用法和常用参数
  • 理解 working tree、index 和 object database 这三层,是看懂 add、commit、restore、reset 的关键前提。
  • 理解 为什么这三层必须分开理解 相关的概念
  • 掌握 1. 工作区是什么 相关的操作
  • 知道在什么场景下使用该命令,什么场景下避免使用

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

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

先想一个问题

你每天都在用 Git 命令,但偶尔会遇到一些 '奇怪' 的行为——比如明明没改文件却被提示有改动,或者 rebase 时突然多了预期之外的冲突。你想理解 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 已经正式记住什么”。

给你的练习

  1. 在一个测试仓库中练习该命令的基本用法,观察执行前后的状态变化
  2. 尝试该命令的不同参数选项,对比输出结果的差异
  3. 模拟一个需要使用该命令的实际场景,完整走一遍操作流程

延伸阅读

沿着同一主题继续深入: