Git 场景速查地图:遇到问题对号入座
# 第8章 · 场景速查
# 一、学完就忘
前七章,小李从 Git 门外汉变成了团队里解决 Git 问题最快的人。同事遇到冲突、误删分支、rebase 搞砸了,都来找他。
但小李自己也有个尴尬的时刻:他经常要停下来想"这个场景该用哪个命令来着?"
某天 Leader 路过他的工位,看到他在快速翻之前写的 Git 笔记,笑着说:
"你缺的不是知识,是一张地图——遇到什么场景,一眼看到用什么命令。"
这就是本章的定位:不是教程,是地图。 你不需要记住 100 个命令,只需要知道「我遇到了什么情况」→「翻到这个区」→「对号入座」。
# 二、速查地图总览
本章按照你日常使用 Git 的真实场景组织,而不是按照命令种类。一共七个区:
工作区的日常 分支操作区
┌──────────┐ ┌──────────────┐
│ 改错了? │ │ 开分支 合并 │
│ add 错了?│ │ 冲突解决 │
│ commit 错了?│ │ rebase │
└──────────┘ └──────────────┘
│ │
└────────── 速查地图 ──────────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
远程协作区 紧急救援区 日常流水线
推送/拉取/PR stash/回退/ 早上一来→
clone/标签 误删/reflog →晚上回家
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
七个区:
- 撤销区——从「还没 add」到「已经 push」,四级撤销
- 分支区——创建、切换、合并、冲突、变基
- 远程区——推送、拉取、克隆、标签
- 救援区——stash、cherry-pick、bisect、reflog
- 清理区——删分支、clean、整理历史
- 查询区——看历史、看差异、追责任人
- 工作流区——早上开机到晚上关机的一整天操作序列
# 三、撤销区
核心原则:先确认改动在哪个区域,再选命令。
工作区(还没 add) → git restore
暂存区(add 了) → git restore --staged
版本库(commit 了) → git reset
远程(push 了) → git revert
1
2
3
4
2
3
4
# 3.1 我改乱了文件,还没 add
# 单个文件
git restore <file>
# 所有文件
git restore .
1
2
3
4
5
2
3
4
5
# 3.2 add 错了,想撤回暂存区
# 单个文件
git restore --staged <file>
# 所有文件
git restore --staged .
1
2
3
4
5
2
3
4
5
# 3.3 commit 了但没 push,想撤销
# 保留修改在暂存区(改 commit message 用)
git reset --soft HEAD~1
# 保留修改在工作区(重新规划 commit 用)
git reset --mixed HEAD~1
# 或直接:git reset HEAD~1(默认 --mixed)
# 彻底丢弃(⚠️)
git reset --hard HEAD~1
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 3.4 已经 push 了,想撤销远程
# 安全方式:生成新 commit 反向抵消
git revert <commit-hash>
git push
# 万不得已才用(⚠️)
git reset --hard <commit-hash>
git push --force-with-lease
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3.5 commit message 写错了 / 漏了文件
# 只改 message
git commit --amend -m "新的提交说明"
# 漏了文件想补进去
git add <漏掉的文件>
git commit --amend --no-edit
# 既改 message 又补文件
git add <漏掉的文件>
git commit --amend -m "新的提交说明"
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 3.6 正在 merge / rebase / cherry-pick 中想放弃
git merge --abort
git rebase --abort
git cherry-pick --abort
1
2
3
2
3
# 四、分支区
# 4.1 创建和切换
# 创建分支
git branch <name>
# 创建 + 切换(推荐)
git switch -c <name>
# 基于指定 commit 创建
git switch -c <name> <commit-hash>
# 基于远程分支创建本地跟踪分支
git switch -c <name> origin/<name>
# 切换分支
git switch <name>
# 列出所有分支
git branch -a # 含远程
git branch -v # 带最新 commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 4.2 合并
# 标准合并(切到目标分支再 merge)
git switch <target>
git merge <source>
# 推荐:保留分支痕迹
git merge --no-ff <source>
# 压缩合并(所有 commit 压成一个)
git merge --squash <source>
git commit -m "feat: xxx"
# 放弃正在进行的合并
git merge --abort
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 4.3 冲突解决标准流程
# 1. 遇到冲突后,查看冲突文件:
git status
# 2. 手动编辑文件,删掉 <<<<<< / ====== / >>>>>> 标记
# 3. 标记已解决:
git add <已解决的文件>
# 4. 如果是 merge:
git commit -m "merge: 解决冲突"
# 如果是 rebase:
git rebase --continue
# 如果是 cherry-pick:
git cherry-pick --continue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4.4 变基
# 把当前分支 rebase 到目标分支
git rebase <target>
# 交互式整理最近 N 个 commit
git rebase -i HEAD~N
# rebase -i 操作:
# pick → 保留
# reword → 改 message
# squash → 合并到上一个,保留两段 message
# fixup → 合并到上一个,丢弃 message
# drop → 删掉这个 commit
# edit → 停下来手改 commit 内容
# 放弃正在进行的 rebase
git rebase --abort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4.5 分支重命名
# 重命名本地分支
git branch -m <旧名> <新名>
# 删除远程旧名,推送新名
git push origin --delete <旧名>
git push -u origin <新名>
1
2
3
4
5
6
2
3
4
5
6
# 4.6 删除分支
# 安全删除(已合并的)
git branch -d <name>
# 强制删除(没合并也删)
git branch -D <name>
# 删除远程分支
git push origin --delete <name>
# 清理本地失效的远程分支引用
git fetch --prune
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 五、远程区
# 5.1 推送与拉取
# 首次推送并建立追踪
git push -u origin <branch>
# 日常推送
git push
# 拉取远程更新(先侦察)
git fetch origin
git log --oneline <branch>..origin/<branch> # 看远程多了什么
git diff <branch> origin/<branch> # 看具体改了什么
# 再决定合并方式
git merge origin/<branch> # 合并(保留分叉历史)
git rebase origin/<branch> # 变基(线性历史)
# 不推荐:直接 pull(= fetch + merge)
git pull
# 推荐:用 rebase 的 pull
git pull --rebase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 5.2 克隆
# HTTPS
git clone https://github.com/user/repo.git
# SSH(推荐,需先配置密钥)
git clone git@github.com:user/repo.git
# 指定本地目录名
git clone <url> <folder-name>
# 只克隆最近一层历史(大项目加速)
git clone --depth 1 <url>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 5.3 远程仓库管理
git remote -v # 查看所有远程
git remote add <name> <url> # 添加远程
git remote rename <old> <new> # 重命名
git remote remove <name> # 删除
git remote set-url origin <new-url> # 修改 URL
1
2
3
4
5
2
3
4
5
# 5.4 标签
# 轻量标签
git tag v1.0.0
# 附注标签(推荐,含作者/日期/message)
git tag -a v1.0.0 -m "正式发布 v1.0.0"
# 列出标签
git tag # 全部
git tag -l "v1.*" # 按模式过滤
# 推送标签(push 默认不推标签!)
git push origin v1.0.0 # 推送单个
git push origin --tags # 推送全部
# 删除标签
git tag -d v1.0.0 # 本地
git push origin :refs/tags/v1.0.0 # 远程(冒号语法)
# 基于标签创建分支(发布后修 bug)
git switch -c hotfix/v1.0.1 v1.0.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 六、救援区
# 6.1 改到一半被叫去修 bug(stash)
# 保存现场(含新文件)
git stash -u -m "备注"
# 查看 stash 列表
git stash list
# 恢复并删除
git stash pop
# 恢复但保留
git stash apply
# 恢复指定的
git stash apply stash@{2}
# 查看 stash 里有什么
git stash show -p stash@{0}
# 删除
git stash drop stash@{1}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 6.2 只把某个 commit 搬到另一个分支(cherry-pick)
# 移植单个
git cherry-pick <hash>
# 移植多个不连续
git cherry-pick <hash1> <hash2> <hash3>
# 只取改动不自动 commit
git cherry-pick -n <hash>
# 冲突了 → 解决 → 继续
git cherry-pick --continue
# 放弃
git cherry-pick --abort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 6.3 不知道哪个 commit 引入的 bug(bisect)
git bisect start
git bisect bad HEAD # 当前是坏的
git bisect good <hash> # 某个版本是好的
# Git 自动跳到中间,你测试后告诉它 good 或 bad
git bisect good # 或 git bisect bad
# 重复直到定位
# 最终输出:xxxxxx is the first bad commit
# 退出二分模式
git bisect reset
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 6.4 误删分支
# 找到删之前的最后一个 commit
git reflog --date=iso
# 用那个 commit 重建分支
git switch -c <分支名> <hash>
1
2
3
4
5
2
3
4
5
# 6.5 reset --hard 之后后悔
git reflog
# 找到 reset 之前的 commit hash
git reset --hard <hash>
1
2
3
2
3
# 6.6 rebase 搞砸了想回去
git reflog
# 找到 rebase 之前的 HEAD@{n}
git reset --hard HEAD@{n}
1
2
3
2
3
# 七、查询区
# 7.1 看历史
git log --oneline # 一行一个
git log --oneline --graph --all # 全局分支图
git log --oneline -5 # 最近 5 个
git log --oneline <file> # 某个文件的历史
git log --oneline --grep="关键词" # 搜索 message
git log --oneline --since="3 days ago" # 按时间过滤
git log --oneline --author="杨充" # 按作者过滤
1
2
3
4
5
6
7
2
3
4
5
6
7
# 7.2 看差异
git diff # 工作区 vs 暂存区
git diff --cached # 暂存区 vs HEAD
git diff HEAD # 工作区 vs HEAD
git diff <hash1> <hash2> # 两个 commit 之间
git diff <hash1> <hash2> -- <file> # 指定文件
1
2
3
4
5
2
3
4
5
# 7.3 追责任人
git blame <file> # 每行的作者+时间+commit
git blame -L 5,15 <file> # 只看指定行
git blame -w <file> # 忽略空白改动
1
2
3
2
3
# 7.4 看状态
git status # 哪些改了、哪些暂存、哪些没跟踪
git status -s # 简短格式
1
2
2
# 7.5 看某个 commit 的详情
git show <hash> # 完整信息(diff + message)
git show --stat <hash> # 只显示改了什么文件
git show <hash>:<file> # 看那个 commit 时的文件内容
1
2
3
2
3
# 八、配置区
# 用户信息
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
# 查看所有配置
git config --list
# 常用别名
git config --global alias.lg "log --oneline --graph --all"
git config --global alias.st "status -s"
git config --global alias.co "switch"
git config --global alias.br "branch"
git config --global alias.undo "reset --soft HEAD~1"
# 全局 gitignore
git config --global core.excludesfile ~/.gitignore_global
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 九、工作流区
# 9.1 早上开机第一件事
git switch develop
git fetch origin
git log --oneline develop..origin/develop # 看看远程有什么新东西
git rebase origin/develop # 同步最新代码
1
2
3
4
2
3
4
# 9.2 开始一个新功能
git switch develop
git pull --rebase origin develop # 确保本地最新
git switch -c feature/xxx # 开分支
# ... 开发 ...
1
2
3
4
2
3
4
# 9.3 开发中同步上游(每天至少一次)
git stash -u -m "暂存,先同步上游" # 保存当前进展
git switch develop
git pull --rebase origin develop # 同步 develop
git switch feature/xxx
git rebase develop # 把 feature rebase 到最新 develop
git stash pop # 恢复
# 如果有冲突,解决 → git rebase --continue
1
2
3
4
5
6
7
2
3
4
5
6
7
# 9.4 功能完成,提 PR
# 1. 整理 commit
git rebase -i HEAD~N
# 2. 推送到远程
git push -u origin feature/xxx
# 3. 去 GitHub/GitLab 创建 Pull Request
# base: develop ← compare: feature/xxx
# 4. 如果审查提出修改意见:
# 本地修改 → git add → git commit → git push
# PR 自动更新
# 5. 审查通过 → Merge
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 9.5 合并完清理战场
git switch develop
git pull origin develop
# 删远程分支
git push origin --delete feature/xxx
# 删本地分支
git branch -d feature/xxx
# 清理失效的远程引用
git fetch --prune
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 9.6 hotfix 紧急修复
# 1. 保存当前工作
git stash -u -m "暂存,修紧急 bug"
# 2. 从 main 开 hotfix
git switch main
git pull origin main
git switch -c hotfix/xxx
# 3. 修复 + 提交
# ... 改代码 ...
git add .
git commit -m "hotfix: 修复 xxx"
# 4. 合回 main
git switch main
git merge --no-ff hotfix/xxx -m "merge: hotfix xxx"
git tag -a v1.0.1 -m "hotfix: xxx"
git push origin main --tags
# 5. 🚨 同步到 develop(否则 develop 上还有这个 bug!)
git switch develop
git merge --no-ff hotfix/xxx -m "merge: 同步 hotfix xxx"
# 6. 清理 + 恢复
git branch -d hotfix/xxx
git switch feature/原来的分支
git stash pop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 9.7 发布新版本
# Git Flow 方式
git switch develop
git pull origin develop
git switch -c release/v1.2.0
# 修 bug、改版本号
# ...
git add .
git commit -m "chore(release): v1.2.0"
# 合并到 main + 打标签
git switch main
git merge --no-ff release/v1.2.0 -m "release: v1.2.0"
git tag -a v1.2.0 -m "v1.2.0 正式发布"
git push origin main --tags
# 同步回 develop
git switch develop
git merge --no-ff release/v1.2.0 -m "merge: 同步 release v1.2.0"
# 清理
git branch -d release/v1.2.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 9.8 晚上关机前
# 确认当前分支状态
git status
git branch -v
# 推送今天的工作
git push origin <current-branch>
# 清理已合并的本地分支
git branch --merged | grep -v "main\|develop" | xargs git branch -d 2>/dev/null
# 安心下班!
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 十、合并策略速选
| 你的情况 | 用什么 | 命令 |
|---|---|---|
| 把整个 feature 合到 develop | merge --no-ff | git merge --no-ff feature |
| 整理自己的分支再提 PR | rebase | git rebase develop |
| 只想同步一个修复到另一分支 | cherry-pick | git cherry-pick <hash> |
| 个人分支保持最新 | rebase | git rebase origin/develop |
| 公共分支合入新功能 | merge --no-ff | 在 GitHub 上 squash merge |
| 合并一个 commit 都没有的临时分支 | merge --squash | git merge --squash feature |
# 十一、重置速选
| 你想 | 用什么 | 修改在哪 |
|---|---|---|
| 改 commit message | reset --soft | 修改留在暂存区 |
| 重新规划 commit 结构 | reset --mixed | 修改留在工作区 |
| 彻底不要了 | reset --hard | 全丢(但 reflog 可救) |
| 已 push,安全撤销 | revert | 生成新 commit 抵消 |
# 十二、全书心法汇总
这七章学下来,Git 的本质可以浓缩成五句话:
- Git 只有三个区域:工作区、暂存区、版本库。一切命令都在这三者之间搬运数据。
- 分支只是一个 40 字节的指针文件。创建分支毫秒级,所以大胆开,频繁合,及时删。
- 永远先 fetch 再决定怎么 merge。盲目
git pull是大多数协作冲突的根源。- 只要 commit 过,就能用
reflog找回来。Git 是后悔药最多的工具——30 天内你做的任何事都有记录。- 团队协作靠纪律,不靠记忆。保护分支 + PR 审查 + Conventional Commits + CI,四件套缺一不可。
# 📎 附录:一份可打印的 Git 命令速查卡片
┌─────────────────────────────────────────────────────────┐
│ Git 场景速查卡片 │
├─────────────────────────────────────────────────────────┤
│ 撤销类 │
│ 还没 add → git restore <file> │
│ add 错了 → git restore --staged <file> │
│ commit 了没 push → git reset --soft HEAD~1 │
│ 已 push → git revert <hash> │
├─────────────────────────────────────────────────────────┤
│ 分支类 │
│ 创建+切换 → git switch -c <name> │
│ 合并 → git merge --no-ff <branch> │
│ 变基 → git rebase <target> │
│ 整理 → git rebase -i HEAD~N │
│ 删本地 → git branch -d <name> │
│ 删远程 → git push origin --delete <name> │
│ 放弃合并 → git merge --abort │
│ 放弃变基 → git rebase --abort │
├─────────────────────────────────────────────────────────┤
│ 远程类 │
│ 推送 → git push │
│ 拉取(安全) → git fetch → git diff → git merge │
│ 克隆 → git clone <url> │
│ 打标签 → git tag -a v1.0.0 -m "msg" │
│ 推标签 → git push origin --tags │
├─────────────────────────────────────────────────────────┤
│ 救援类 │
│ 暂存 → git stash -u -m "msg" │
│ 恢复 → git stash pop │
│ 移植 → git cherry-pick <hash> │
│ 后悔 → git reflog │
│ 二分找 bug → git bisect start → good/bad │
├─────────────────────────────────────────────────────────┤
│ 查询类 │
│ 看历史 → git log --oneline --graph --all │
│ 看差异 → git diff │
│ 看状态 → git status │
│ 追责 → git blame <file> │
│ 看远程多了什么 → git log HEAD..origin/main │
└─────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
上次更新: 2026/06/07, 10:26:12