外观
00 · 先读这个:三区与提交图
后面每一条命令都在改下面这几层里的某一层。分不清层次,就会把「撤出暂存区」做成「丢掉全部改动」,把「本地回退」做成「覆盖远程」。
仓库里到底有什么

| 层 | 英文 | 是什么 | 典型命令 |
|---|---|---|---|
| 工作区 | Working Tree / Working Directory | 磁盘上你正在改的文件 | 编辑器、restore、clean |
| 暂存区 | Index / Staging Area | 「下次 commit 要拍进去的清单」 | add、restore --staged |
| 本地历史 | Commits + 分支指针 + HEAD | 已经拍好的不可变快照,用指针串成图 | commit、reset、rebase |
| 远程跟踪分支 | Remote-tracking branch | 上次 fetch 时远程长什么样,只读缓存 | fetch 更新它 |
| 远程仓库 | Remote | GitHub / GitLab / 公司服务器上的副本 | push 才改它 |
origin/main 不是远程本身,是你电脑上的一份「远程快照」。所以:
git fetch:只更新这份快照,不动你的工作和分支。git pull:fetch 完再把变化合并(或 rebase)进当前分支。git push:把本地提交送到远程,别人下次 fetch 才能看见。
提交是快照,分支是指针
一次 commit 记录的是当时整个项目的快照(加上作者、时间和父提交),不是「相对上一版的 diff」。Git 显示 diff 是比较两个快照算出来的。
分支名(main、feature/login)只是贴在某个 commit 上的可移动指针。HEAD 通常指向当前分支名,再由分支名指向 commit:

你再提交一次,main 和 HEAD 一起挪到新的 C5,旧的 C3 还在,只是没有分支指着它时,过一段时间可能被垃圾回收。在回收之前,git reflog 还能找到它。 这就是误操作能救回来的根本原因。
detached HEAD(游离 HEAD)
HEAD 也可以直接指某个 commit,而不经过分支名:
bash
git switch --detach v1.2.0
# 或旧写法:git checkout v1.2.0
# 或:git checkout a1b2c3d这时你是在「参观历史」。在这里做的新提交没有分支保护,一切换分支就像把梯子撤走。
做错了怎么办: 先别切走,立刻:
bash
git switch -c rescue/from-detached把当前提交接到一条新分支上。已经切走了,去 急救手册 · detached HEAD。
四个问题,判断任何命令
碰到不熟悉的命令,按顺序问:
- 它改哪一层? 只读 / 工作区 / 暂存区 / 本地历史 / 远程。
- 改动进过 Git 吗? 没
add过的,Git 基本帮不了;进过暂存或 commit 的,多半能找。 - 提交推过没有? 没 push:
reset/amend都可以。已 push 到共享分支:用revert。 - 有没有别人基于这些提交继续工作? 有,就不要改写历史,也不要
--force。
安全等级
全文命令都会标其中一档:
| 等级 | 含义 | 例子 |
|---|---|---|
| 只读 | 不改任何层,放心敲 | status、log、diff、show、blame |
| 可逆本地 | 改工作区或暂存区,可用对称命令还原 | add、restore --staged、switch(干净时) |
| 改写未推送历史 | 改本地 commit 图;推送前可用 reflog 反悔 | commit --amend、rebase、reset |
| 影响远程 | 别人会看到;共享分支上要沟通 | push、push --force-with-lease |
| 危险 | 可能丢掉未入库内容,或覆盖别人的远程历史 | reset --hard、clean -fd、push --force、branch -D |
「危险」不是禁止,是:先确认 reflog / dry-run / 是否已 push,再执行。
switch / restore 和 checkout
老教程满屏 git checkout。现行 Git 把它拆成两个更不容易点错的命令:
| 你想做的事 | 现在用 | 旧写法 |
|---|---|---|
| 切换 / 新建分支 | git switch、git switch -c | git checkout、git checkout -b |
| 恢复文件内容 | git restore、git restore --staged | git checkout -- 文件、git reset HEAD 文件 |
本指南正文用新命令,并在对应小节标注旧写法。两者都有效,混用时分清「切分支」和「改文件」。
日常最小闭环
把代码从编辑器送到远程,通常就是:
bash
git status # 看改了什么
git add -p # 挑选要提交的块
git commit -m "fix: 登录校验空密码"
git pull --rebase origin main # 或先 fetch 再 rebase / merge
git push -u origin HEAD每一步对应哪一层、失败了去哪一章,后面按场景展开。
下一章:01 · 配置、身份与忽略规则