02 — 三区模型:工作区、暂存区、仓库
02 — 三区模型:工作区、暂存区、仓库
写在前面:这一章要解决什么
如果你刚学完「Git 是什么」,心里可能还有一个更具体的困惑:
我在编辑器里点了「保存」,为什么 Git 还说「没有东西可提交」?
这一章就是专门回答这个问题的。
学完后,你应该能:
- 用自己的话说明:文件在 Git 里会待在哪三块地方
- 分清「保存文件」和「提交历史」不是一回事
- 看懂
git status在说什么(哪一块脏了) - 知道
git add和git commit各自干了哪一步
读者设定:大一同学,几乎没有做过团队项目,可以把 Git 想成「会记作业历史的工具」。
1. 定位:为什么要先讲「三块地方」
1.1 一句话先记住
Git 管文件时,不是只有一个「文件夹」,而是有三块地方在配合:
| 白话名字 | 教材里的名字 | 你现在先这样理解 |
|---|---|---|
| 书桌 | 工作区 | 你正在改、正在看的那些文件 |
| 待交作业篮 | 暂存区 | 「下次要正式记进历史的那一叠」 |
| 档案柜 | 本地仓库 | 已经正式记下的一版版历史(藏在.git里) |
很多人卡住,是因为把这三块当成了一块。
1.2 生活里的类比(先建立感觉)
想象你在写课程报告:
- 书桌上摊着 Word / 代码,你边改边保存——这是「书桌」。
- 写到一个小段落满意了,你把它放进「待交作业篮」,准备等会儿一起交——这是「暂存区」。
- 你决定「这一阶段算完成了」,把篮子里的内容正式登记进档案(还写一句说明:今天完成了什么)——这是「提交到仓库」。
关键点:
- 只在书桌保存 →档案柜里还没有新记录
- 放进篮子但还没正式登记 →历史里仍然没有这一笔
- 只有「放进篮子 + 正式登记」两步都做完 → 才算真正记进 Git 历史
图:书桌(工作区)→ 待交作业篮(暂存区)→ 档案柜(仓库)。箭头对应git add与git commit。
1.3 和你已经会的事对比
| 你已经会的 | 容易误以为 | 其实 |
|---|---|---|
| 编辑器「保存」 | 等于 Git 记了一笔历史 | 只改了书桌(工作区) |
| 另存为很多副本 | 等于版本管理 | 没有统一说明、难对比、难协作 |
| 网盘自动历史 | 等于 Git | 网盘很少按「你主动说明为什么改」来记;Git 强调你自己提交并写说明 |
| 第 01 章:Git ≠ 网站 | 学 Git 就是学 GitHub | 本章先只谈本机三块地方,还不谈上传 |
认知锚点:
保存是给「现在的你」看的;提交是给「以后的你 / 同学 / 助教」留证据的。
1.4 本章内容目标(学完能做什么)
| 目标 | 你能做到的事 |
|---|---|
| 说清模型 | 指着图讲清三块地方 |
| 读状态 | 看git status知道文件在书桌还是在篮子里 |
| 会两步 | 会用git add、git commit完成一次「记历史」 |
| 会对比 | 知道git diff和「看已暂存差异」分别在比什么 |
| 少踩坑 | 不再以为「保存了就等于提交了」 |
2. 本质:三块地方到底是什么
2.1 先看总图
图:工作区、暂存区、仓库,以及add/restore/commit的方向。
再看简化流程:
图:日常两步——git add放进暂存区,git commit记进仓库。
2.2 用白话拆开三块
(1)工作区 = 你的书桌
- 就是你在资源管理器 / 编辑器里看到的那些项目文件。
- 你改代码、改报告、点保存,都发生在这里。
- 只改工作区时,Git 的历史还不会自动多一笔。
(2)暂存区 = 待交作业篮
- 英文教材常叫staging area或index(专有名词,记住即可)。
- 作用:让你挑选「下一次正式记录要包含哪些改动」。
- 可以只放一个文件,也可以放很多文件;不必一次把书桌上所有乱七八糟的东西都交出去。
- 在磁盘上,它对应仓库里的
.git/index这类内部文件(现在不用深究格式)。
(3)仓库 = 档案柜(本机历史)
- 真正的历史记录在项目下的隐藏目录
.git里。 - 每一次
git commit,相当于往档案柜里塞进一张「当时项目长什么样」的快照,并写一句说明。 - 以后可以回看、对比、在出问题时找回思路。
2.3 文件在 Git 眼里的「人生阶段」
除了「三块地方」,入门教材(如 Pro Git)还会用文件状态来说事。对大一同学,可以先记四类感觉:
| 白话状态 | 大致意思 | 常见下一步 |
|---|---|---|
| 未跟踪 | Git 还不认识这个新文件 | git add告诉它「请开始管」 |
| 已修改但未暂存 | 老文件改了,但还没放进篮子 | git add放进篮子 |
| 已暂存 | 已在篮子里,准备正式登记 | git commit |
| 干净 | 书桌和档案柜一致,没什么要交的 | 继续写新内容 |
图:文件从「未跟踪 → 已暂存 → 已提交 → 又被修改」的常见循环。来源:Pro Git 中文版《记录每次更新到仓库》(知识共享署名-非商业性使用-相同方式共享 3.0)。
小提示:上图英文标签是原书附图;你只要抓住箭头方向:改 → 加入暂存 → 提交 → 再改。
2.4 必须先接受的几条「硬规矩」
| 规矩 | 白话解释 |
|---|---|
| 保存 ≠ 提交 | 保存只动书桌;提交才进档案柜 |
不add就commit,常常等于「篮子是空的」 | 仓库不会自动猜你想交哪份 |
| 暂存的是「某一时刻的内容」 | add之后又改文件,要再add一次,篮子里才是最新 |
| 未跟踪文件默认不会进历史 | 除非你明确add,或以后学忽略规则 |
| 先看状态再提交 | git status是仪表盘,养成习惯 |
2.5 新手最常踩的坑
| 现象 | 原因 | 怎么办 |
|---|---|---|
明明改了,git diff却是空的 | 改动可能已经在暂存区里 | 再看「已暂存的差异」(见后文) |
nothing to commit | 篮子是空的,或根本没改已跟踪文件 | 先git status,再决定是否add |
| 提交了不该交的文件 | git add .加得太猛 | 先列文件名再加;重要文件一个一个加 |
| 以为提交了就上传到网上了 | 提交默认只在本机档案柜 | 上传是以后「远程」章节的事 |
3. 建议的学习顺序
先建立书桌比喻 → 看三区总图 → 动手:新建文件,看状态 → git add,再看状态 → git commit,再看状态 → 学会两种「看差异」 → 完成章末小实验不要一上来背很多参数。这一章只要求状态说得清、两步走得顺。
4. 动手准备(可丢弃目录)
请找一个可以随便删的练习目录,不要用正在交的作业仓库练手。
mkdirlab-three-treescdlab-three-treesgitinit-bmaingitconfig user.name"Ada Example"gitconfig user.email"ada@example.com"说明:
git init -b main:在本目录创建 Git 仓库,初始分支名叫main- 名字和邮箱只是写在提交记录上的「作者信息」(演示用虚构身份即可)
- 本系列命令样例在 Linux 上用Git 2.43.0验证过;你电脑版本接近即可
git--versiongit version 2.43.05. 跟着做:看清「文件在哪一块」
5.1 只在书桌新建文件(还没告诉 Git)
printf'hello\n'>notes.txtgitstatus输出会类似(你的提示语言可能是中文或英文,意思相同):
On branch main No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) notes.txt nothing added to commit but untracked files present (use "git add" to track)白话翻译:
- 你在分支
main上 - 还没有任何正式提交
notes.txt是未跟踪的:Git 看见了它,但还没开始正式管理- 所以「没有可提交的内容」——因为篮子还是空的
| 这一步动了哪一块? | 答案 |
|---|---|
| 工作区 | 有了新文件 |
| 暂存区 | 还没有 |
| 仓库历史 | 还没有新提交 |
5.2 放进待交作业篮:git add
gitaddnotes.txtgitstatusOn branch main No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: notes.txt白话翻译:
- 出现了 “Changes to be committed” 一类提示:意思是篮子里已经有货了
notes.txt已是「新文件、已暂存」
| 命令 | 副作用(你要记住的) |
|---|---|
git add 文件名 | 把该文件当前内容放进暂存区;不会自动完成提交 |
| 是否上传网络 | 不会 |
5.3 正式记进档案柜:git commit
gitcommit-m"docs: 添加课堂笔记草稿"gitstatus提交成功时,会看到类似:
[main (root-commit) ........] docs: 添加课堂笔记草稿 1 file changed, 1 insertion(+) create mode 100644 notes.txt再看状态,通常会变成「工作区干净」一类提示。
白话翻译:
- 档案柜里有了第一笔正式历史
-m后面是你写的说明:以后回看时靠它回忆「当时为什么改」- 第一次提交有时叫「根提交」(没有更早的父提交)
| 命令 | 副作用 |
|---|---|
git commit -m "说明" | 把暂存区里的内容记成一笔提交;推进当前分支 |
| 没放进暂存区的修改 | 不会被这次提交带走 |
5.4 再改一次:看清「改了但还没进篮子」
printf'hello v2\n'>notes.txtgitstatus你会看到文件变成已修改,并且往往在「尚未暂存」一类区域。
gitdiffgit diff(不加额外参数)主要回答:
书桌相对「篮子」多改了什么?
若你已经add过、想看「篮子相对上一笔提交」多了什么,要用:
gitdiff--staged(有的资料也写--cached,意思同类。)
| 命令 | 白话在比什么 |
|---|---|
git diff | 书桌 ↔ 暂存区 |
git diff --staged | 暂存区 ↔ 最新提交 |
git status | 用清单告诉你文件大概在哪一阶段 |
这就是入门书里反复强调的「两种差异」:没看清就容易觉得 Git「输出是空的、坏了」。
5.5 一个容易晕的点:add之后又改文件
顺序如果是:
- 修改文件 →
git add - 再改同一文件
- 直接
git commit
那么:提交进去的,是第 1 步放进篮子时的版本,不是你第 2 步书桌最新版。
办法:改完再git add一次,让篮子更新,再提交。
6. 命令按「用途」分组(先少后多)
6.1 看状态(只读,放心用)
| 命令 | 干什么 |
|---|---|
git status | 总览:哪些未跟踪、哪些已改、哪些已暂存 |
git status -s | 更短的一行式状态(熟练后好用) |
git diff | 看「还没进篮子」的改动细节 |
git diff --staged | 看「已经在篮子里、准备提交」的改动细节 |
6.2 在三块地方之间搬东西
| 命令 | 从哪到哪 | 备注 |
|---|---|---|
git add 路径 | 工作区 → 暂存区 | 新文件、改过的文件都靠它放进篮子 |
git commit -m "说明" | 暂存区 → 仓库 | 正式记历史 |
git restore 文件 | 丢掉工作区里未提交的修改(危险,先确认) | 下一章会系统讲撤销 |
git restore --staged 文件 | 把文件从篮子拿回(取消暂存) | 文件内容通常还在书桌上 |
现在你只要建立印象:撤销也分「撤书桌」还是「撤篮子」,不要乱用「重置」类强力命令。
6.3 和「整份作业一次交」的对比
| 做法 | 优点 | 缺点 |
|---|---|---|
总是git add .然后提交 | 快 | 容易把临时文件、密码文件一起交进去 |
先status,再按文件add | 清楚、安全 | 慢一点点 |
| 以后学的「挑选片段再暂存」 | 更精细 | 大一稍后学即可 |
大一建议默认:先git status,再决定加哪些文件。
7. 对照表:降低记忆负担
7.1 三块地方对照
| 工作区 | 暂存区 | 仓库 | |
|---|---|---|---|
| 比喻 | 书桌 | 待交作业篮 | 档案柜 |
| 你每天怎么碰到 | 编辑、保存 | git add | git commit |
| 关电脑重启后还在吗 | 文件还在 | 还在(在.git里) | 还在 |
| 等于上传到网上了吗 | 否 | 否 | 否(仍是本机) |
7.2 「保存」和「提交」对照
| 动作 | 给谁看 | 有没有「为什么改」的说明 | 能不能当正式历史回看 |
|---|---|---|---|
| 编辑器保存 | 现在的你 | 通常没有 | 弱(只有当前文件) |
git commit | 未来的你 / 同学 | 有提交说明 | 强(一笔笔记录) |
7.3 状态报告怎么读(对照 Pro Git 的讲法)
当你执行git status时,可以按这个顺序读:
- 我在哪个分支?
- 有没有「将要提交的更改」(篮子里有没有货)?
- 有没有「尚未暂存的更改」(书桌改了但没进篮子)?
- 有没有「未跟踪文件」(新面孔)?
读完这四句,你就知道下一步是add、commit,还是继续改。
8. 安全习惯(现在就能养成)
8.1 建议这样做
| 习惯 | 原因 |
|---|---|
每次提交前先git status | 避免交错文件 |
| 提交说明写人话 | 一周后自己还看得懂 |
| 一次提交只做一类事 | 以后好回退、好检查 |
| 在可删除的练习目录练手 | 不怕点错 |
密钥、密码文件不要add | 进历史很难彻底抹掉 |
8.2 暂时不要这样做
| 别急着用 | 原因 |
|---|---|
| 在正式大作业仓库乱试「强制重置」 | 可能丢掉未提交修改 |
还没会看status就狂用图形按钮 | 出问题说不清状态 |
| 把「提交」理解成「已经交给老师网站」 | 本机提交 ≠ 上传 |
8.3 推荐的最小循环(背下来)
# 1. 改文件并在编辑器保存# 2. 看状态gitstatus# 3. 需要的话看差异gitdiff# 4. 放进篮子gitadd某个文件# 5. 再确认篮子gitstatus# 6. 正式记录gitcommit-m"用一句话说明这次改了什么"# 7. 确认干净gitstatus图:编辑 → 看状态 → 加入暂存 → 提交 → 再查看。
9. 真实场景(没有项目经验也能懂)
9.1 写课程大作业
你写了一晚上报告:
- 每完成一节,就
add+commit一次,说明写「完成第三节实验步骤」。 - 中途改乱了,至少还能对照某一节完成时的版本。
这比桌面上堆最终版-真的最终.docx清醒得多。
9.2 只想提交「修错别字」,不想提交「还没写完的新章节」
- 错别字文件:
git add - 未完成章节:先别
add - 然后
commit
这正是暂存区存在的理由:允许你挑选要记进历史的部分。
9.3 和同学协作之前
协作上传、拉取是后面章节。但现在就要养成:
- 本机历史清晰
- 每次提交说得清
否则文件一合并,更难沟通「你改的是哪一版」。
9.4 误以为「网盘同步文件夹」就够了
网盘适合备份;Git 适合:
- 看清改了哪几行
- 写明为什么改
- 以后按历史回退思路
大一先建立 Git 习惯,以后做课设、实习会轻松很多。
10. 稍微多懂一点点(可选)
- 暂存区不是可有可无的界面装饰,它是 Git 设计的核心步骤之一。
- 仓库历史在
.git里;删掉.git约等于丢掉 Git 历史(工作区文件可能还在)。 - 图形界面(编辑器侧边栏)底层仍是这三块地方;会看
status的人,用任何界面都更稳。 - 更底层的「对象、哈希」放到原理篇再讲;本章够用。
11. 小实验(请一定动手)
实验甲:只提交一个文件
- 新建仓库,创建
a.txt和b.txt。 - 只把
a.txt加入暂存并提交。 - 用
git status确认:b.txt仍在「未跟踪」或未提交状态。
通过标准:你能说清为什么b.txt没有进那次提交。
实验乙:两种差异
- 修改已提交的文件,先不
add,运行git diff。 - 再
git add,运行git diff和git diff --staged,观察区别。
通过标准:能用「书桌 / 篮子 / 档案柜」解释两次输出为什么不同。
实验丙:add后又改
- 修改 →
add→ 再修改 → 直接commit。 - 检查提交进去的内容是不是「中间那一版」。
- 再
add+commit把最新版补上。
通过标准:你再也不会默认「commit 一定会带走书桌上最新内容」。
12. 常见问题
问 1:我可以跳过暂存区吗?
有些命令可以「对已跟踪文件直接提交」,但对新手不推荐当默认习惯。先把三区走顺,再学快捷方式。
问 2:git add .可以一直用吗?
练习可以。真正作业里更建议先status,避免把临时文件加进去。
问 3:提交了是不是老师就能看见?
默认不能。提交在你电脑的档案柜里。要让别人看见,需要以后学的远程推送。
问 4:状态输出是英文看不懂?
先抓关键词:Untracked(未跟踪)、Changes to be committed(将要提交 / 已在篮子)、Changes not staged(改了还没进篮子)、nothing to commit(没什么可交)。中文环境下也会有对应翻译。
问 5:为什么要写提交说明?
给未来的自己看。一个月后你不会记得「那天晚上改乱的是哪一处」。
问 6:三区模型和「分布式」什么关系?
三区是本机怎么记历史;分布式是多台电脑 / 远程怎么同步。先本机,后远程。
问 7:图形按钮和命令行哪个好?
先命令行建立词汇,再用图形加速。出问题时,能读status比会点按钮更重要。
问 8:我需要把.git交到作业压缩包里吗?
按老师要求。若老师只要源码,可能不需要;若老师要看提交历史,可能需要整个仓库。不确定就问清楚。
13. 总结、学习路线与思维升华
13.1 这一章请记住的
| 点 | 记住什么 |
|---|---|
| 三块地方 | 工作区、暂存区、仓库 |
| 关键区别 | 保存 ≠ 提交 |
| 两步走 | 先add再commit |
| 仪表盘 | 提交前永远先status |
| 两种差异 | 未暂存差异 / 已暂存差异 |
| 下一章预告 | 撤错时,要说清撤的是哪一块 |
13.2 在整个系列中的位置
01 认识 Git、装好工具 02 三区模型 ← 当前(最重要的地基) 03 日常:提交与查看历史 04 安全地撤销 05 分支与合并 06 远程协作 ……13.3 思维升华
Git 不是自动备份软件,而是「你主动挑选、主动说明」的历史记录工具。
先问「文件现在在书桌、篮子,还是档案柜」,再决定按哪个键。
把状态说清楚,比背一百个参数更重要。
13.4 参考资料
以下资料帮助校对了本章难度与术语;图示署名见仓库内说明文件。
- Pro Git 中文版 — 记录每次更新到仓库(文件状态、暂存、提交的经典讲法;文件生命周期图)
- Pro Git 中文版 — 起步
- git status 说明
- git add 说明
- git commit 说明
- git diff 说明
- 本仓库图示署名:
assets/diagrams/ATTRIBUTION.md
命令输出样例验证环境:Git 2.43.0;演示作者信息为虚构:Ada Example <ada@example.com>。
13.5 本章检查清单
- 能用「书桌 / 篮子 / 档案柜」讲清三区
- 能解释为什么「保存了还不等于提交了」
- 会在练习目录里完成:新建 →
add→commit - 会读
git status的四个关键信息 - 知道
git diff和git diff --staged的差别 - 知道
add之后又改文件要再add - 提交前会先看状态,而不是闭眼提交
你真正「会用 Git」的起点,不是背命令,而是:随时说得出文件现在待在哪一块。
下一章我们会在这个模型上,把日常提交、查看历史跑得更熟。
