在大屏或电脑上体验更佳——动画和操作区域更宽敞。
输入

Git 的四个区域

add、commit、push 跨越不同边界,不能都当成“保存”。工作区、索引、本地仓库和远程仓库可能保存不同版本;跟踪每个区域的快照,才能理解暂存后再编辑、提交后未推送等状态。

Git 四个区域如何工作

  • 工作区是检出的文件集合,编辑器直接读写它。
  • 索引也叫暂存区,代表下一次提交的候选树。
  • 本地仓库保存提交对象和 main 等本地分支引用。
  • 远程仓库保存自己的对象和 refs/heads/main 等分支引用。本课把服务端分支标成 origin: main,以区别本地 main。

索引是完整候选快照,不是提交后就清空的待办箱。git add app.py 将当前 app.py 内容写入索引。随后再编辑文件,只改变工作区,不会暗中改写索引。

提交保存的是索引所表示的树,再以当前 HEAD 作父提交(第一个提交没有父提交)并加入消息,创建提交对象,移动当前分支引用。它不是从工作区直接读取全部内容,也不是一袋独立修改。因此同一路径可以同时有已暂存旧版和未暂存新版。

git push 传输远程缺少的提交等对象,并请求推进远程分支引用,不直接上传当前工作文件或索引。

Git 四个区域逐步演示

默认只使用一个文件和一个分支。

  1. edit app.py 把 print("one") 写入工作区,索引、本地仓库和远程仓库仍为空。
  2. git add app.py 将 print("one") 写入索引。工作文件仍在原位,这是复制内容而非移走文件。
  3. 再次编辑,把工作文件改为 print("two")。索引仍是 print("one"),同一路径出现两份不同快照。
  4. git commit -m "save staged one" 从索引创建 C1,因此 C1 保存 print("one")。本地 main 移到 C1,工作区的 print("two") 仍未提交。
  5. git push origin main 把 C1 传到远程,远程 main 移到 C1。两个仓库分支末端相同,但工作区仍与提交不同。

第 4 步不会保存编辑器中的最新版。提交读取的是“已暂存哪棵树”,所以要把新版提交出去,必须先再次 add。

各边界比较什么

动画在相邻区域之间显示比较状态。

边界状态含义
工作区与索引same已跟踪文件内容与索引相同
工作区与索引unstaged工作内容与候选快照不同
索引与本地 HEADnothing staged树相同,普通提交没有新树可保存
索引与本地 HEADstaged索引与 HEAD 的树不同
本地 main 与远程 mainup to date指向同一提交
本地 main 与远程 mainahead by N本地能到达 N 个远程分支尚不能到达的提交

这些是快照和引用的比较,不表示数据永远从左向右流动。真实 Git 还可从索引恢复文件、重置引用、获取远程对象、合并历史。本课只展示日常编辑、暂存、提交、推送的路径。

边界情况

本课允许执行不产生变化的命令,这些结果属于模型的一部分。

  • app.py 不存在时执行 add,索引不变。本课不展开真实 Git 的缺失路径报错和删除暂存区别。
  • 工作文件与索引相同时,再 add 仍复制相同内容,状态不变。
  • 索引与 HEAD 相同时,普通 commit 报告无暂存修改。工作区有未暂存编辑也不改变这个结果。
  • 尚无本地提交时 push,没有对象可传。
  • 两边 main 已相同时,push 成功但无变化,表示已是最新。

加载快照分叉预设后直接提交,会保存较旧的暂存版。加载未暂存修改预设后不 add 就提交,不会创建提交。两者用来区分索引的作用。

常见错误

  • “add 只是告诉 Git 哪些文件改了。” Git 已能比较差异;add 将选中内容写入索引。再次编辑后若要提交新版,需要再次暂存。
  • “commit 保存项目目录里的所有内容。” 它保存索引,未跟踪和未暂存内容可能不在其中。
  • “提交后暂存区清空。” 索引通常与新 HEAD 相同,不是空了;“无暂存修改”说的是差异为空。
  • “push 发送最新文件。” 推送协商、传输提交并更新远程引用,未进入本地提交的文件内容不会随 push 到达远程。
  • “origin/main 就是远程本身。” 它是本地的远程跟踪引用,由 fetch 等操作更新。服务端另有自己的 refs/heads/main,本课写作 origin: main,两者不是同一个引用。

模型简化

本课只有一个文件、一条线性分支、C1 等合成提交标识,以及始终可用的远程。没有展示 blob/tree 对象细节、分离 HEAD、合并、变基、标签、上游配置、远程跟踪滞后、认证、钩子、打包和网络故障。真实命令可能跨越不止一个边界,但四个区域仍需区分。