Git 命令图解手册:写给实习生的 30 个高频命令
Git 命令图解手册:写给实习生的 30 个高频命令
你以为自己在用 Git,其实你只是在用
add / commit / push。当你遇到分支冲突、reset --hard、误删文件时手足无措,说明你还没真正"看见"Git 内部的运作。这篇博客的核心目的:用图把每个命令的作用讲清楚。建议你打开终端,跟着博客的命令一起敲一遍。
为什么需要图示?
很多 Git 教程是这么写的:
git reset --hard HEAD~1表示回退到上一个版本。
你看完之后依然不知道会发生什么——是只动版本库?工作区的文件还在不在?我改了一半的代码会不会丢?
Git 的所有命令,本质上都是操作"对象":commit、分支指针、工作区文件、暂存区文件。图示能让你直接看到这些对象怎么变,比任何文字描述都清楚。
本博客约定:
*表示一个 commit 节点- 括号里的
(HEAD -> main)表示 HEAD 指针和 main 分支指针都指向这里 - 箭头
→表示命令的方向 - ⚠️ 标记代表危险操作
入门:理解 Git 的三个区域
这是全篇的基石,所有命令都围绕这三个区域运作:
| 区域 | 含义 | 类比 |
|---|---|---|
| 工作区(Working Directory) | 你实际编辑的文件 | 办公桌上的草稿 |
| 暂存区(Stage / Index) | 准备提交的文件"中间站" | 待提交的文件夹 |
| 版本库(Repository) | 已提交的历史记录 | 归档柜 |
┌─────────────┐ git add ┌─────────────┐ git commit ┌─────────────┐
│ │ ──────────────► │ │ ───────────────► │ │
│ 工作区 │ │ 暂存区 │ │ 版本库 │
│ (Working) │ ◄────────────── │ (Stage) │ │ (Repository)│
│ │ git checkout │ │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
▲ │
│ │
└──────────────── git reset ──────────────────────────────────────┘
记住这张图,所有 Git 命令都是在这个图上画箭头。接下来每个命令都对应到这张图上。
辅助命令:
git status:看三个区域分别有什么文件git diff:看工作区和暂存区的差异git diff --staged:看暂存区和版本库的差异
第一章:基础工作流
1. git init — 初始化仓库
git init
把当前目录变成 Git 仓库(生成一个隐藏的 .git 文件夹)。
之前: 之后:
my-project/ my-project/
├── src/ ├── .git/ ← 新增
├── README.md ├── src/
└── main.py ├── README.md
└── main.py
2. git clone <url> — 克隆远程仓库
git clone https://github.com/xxx/yyy.git
把远程仓库完整下载到本地(包含所有历史、分支、tag)。
3. git add <file> — 添加到暂存区
git add hello.txt # 添加指定文件
git add . # 添加当前目录所有变更
之前(hello.txt 是红色): 之后(hello.txt 是绿色):
工作区: hello.txt (未跟踪/修改) 工作区: hello.txt
暂存区: (空) 暂存区: hello.txt ← 新增
版本库: (旧版本) 版本库: (旧版本)
4. git commit -m "msg" — 提交到版本库
git commit -m "feat: add login page"
把暂存区的内容保存为一个 commit,永久进入版本库。
每次 commit 都会生成一个节点:
* c3 (HEAD -> main) feat: add login page
*
* c2 fix: button style
*
* c1 init project
⚠️ 注意:commit 只提交暂存区的内容。如果改了文件但没 add,改的内容不会被提交。
5. git log — 查看提交历史
git log # 详细
git log --oneline # 简洁模式
git log --oneline --graph # 图形化显示分支
$ git log --oneline --graph
* 8f3a21d (HEAD -> main) feat: add login page
* 3b2c109 fix: button style
* a1d4e88 init project
6. git push / git pull — 与远程同步
git push origin main # 推送到远程 main
git pull origin main # 拉取并合并远程 main
本地: * c3 (HEAD -> main) ← git push ───► 远程:* c3 (origin/main)
* ◄── git pull ── *
* c2 * c2
7. .gitignore — 忽略文件
# .gitignore
target/
*.log
.idea/
.DS_Store
被忽略的文件不会出现在 git status 中,也不会被误提交。
第二章:分支管理(重点)
1. 核心认知:分支就是一个指针
很多人误以为"分支是一份代码拷贝"。不对。在 Git 里,分支只是一个指向某个 commit 的可移动指针,非常轻量。
┌── * c4 (feature) feature 分支指针
│
* c3 (HEAD -> main) main 分支指针 + HEAD
*
* c2
*
* c1
2. git branch 系列
git branch # 查看所有本地分支
git branch feature-x # 创建分支(指针指向当前 commit)
git branch -d feature-x # 删除已合并的分支
git branch -D feature-x # ⚠️ 强制删除(未合并也会删)
3. git checkout / git switch — 切换分支
git switch feature-x # 推荐写法(语义清晰)
git checkout feature-x # 老写法,也能切换分支
切换前: 切换后:
* c3 (HEAD -> main) * c3 (HEAD -> feature-x) ← HEAD 移动到 feature
|
* c2
|
* c1
4. git merge — 合并分支
合并有两种情况,结果完全不同:
情况 a:快进合并(Fast-forward)
当 feature 分支没有"分叉"时(main 没新提交),合并只是把 main 指针前移。
合并前: 合并后:
* c4 (feature) * c4 (HEAD -> main, feature) 指针前移
*
* c3 (main)
*
* c2
*
* c1
情况 b:三方合并(生成 merge commit)
当两个分支都有新提交时,Git 会生成一个特殊的 merge commit。
合并前: 合并后:
* c4 (feature) * c5 (HEAD -> main) merge commit
| |\
* c3 (main) * c4 (feature)
| |
* c2 * c3
| |
* c1 * c2
|
* c1
5. git rebase — 变基
rebase 把当前分支的所有提交"摘下来",在目标分支的最新 commit 后面重新播放一遍。结果是一条直线。
merge 后的历史(分叉): rebase 后的历史(一条直线):
* c5 (merge) * c4' (HEAD -> feature)
|\ * c3'
* c4 (feature) * c2
| * c1
* c3 (main)
|
* c2
|
* c1
什么时候用哪个?
| 场景 | 推荐 |
|---|---|
| 团队协作的共享分支(如 main) | merge(保留分叉历史) |
| 自己的本地 feature 分支 | rebase(让历史更干净) |
⚠️ 黄金法则:永远不要对已经推送到远程的 commit 做 rebase,否则团队成员会陷入混乱。
6. 冲突解决
当两个分支改了同一文件的同一行,Git 会停下来让你手动解决:
<<<<<<< HEAD
这是 main 分支的写法
=======
这是 feature 分支的写法
>>>>>>> feature
解决步骤:
- 手动编辑文件,决定保留哪一段(或者合并)
- 删除
<<<<<<<、=======、>>>>>>>标记 git add <file>标记冲突已解决git commit完成合并
第三章:版本回退与恢复(最容易翻车)
1. git reset — 移动 HEAD 指针
⚠️ reset 会改写历史,已经 push 到远程的 commit 不要轻易 reset。
reset 有三种模式,对应不同的"破坏力":
| 模式 | HEAD 移动 | 暂存区重置 | 工作区重置 | 适用场景 |
|---|---|---|---|---|
--soft | ✓ | ✗ | ✗ | 撤销 commit,但保留改动想重新提交 |
--mixed(默认) | ✓ | ✓ | ✗ | 撤销 commit + 撤销 add,文件改动保留在工作区 |
--hard | ✓ | ✓ | ✓ | ⚠️ 彻底回退,所有未提交的改动全丢 |
执行 git reset --hard HEAD~1 后:
之前: 之后:
* c3 (HEAD -> main) * c2 (HEAD -> main) ← HEAD 回退
* *
* c2 * c1
* *
* c1 (c3 在 reflog 里还能找到)
⚠️ --hard 是不可逆的吗? 不一定,见后面的 git reflog。
2. git revert — 安全的撤销
reset 是"删除历史",revert 是"新增一个反向 commit"。已 push 的提交撤销用 revert,不要用 reset。
reset(删除 c3): revert(新增 c3' 反向修改):
* c4 * c4' (HEAD -> main) 新提交
* *
* c3 (被删除) * c3 ← 还在
* *
* c2 * c2
* *
* c1 * c1
用法:
git revert <commit-hash>
# 撤销 merge commit 时需要指定主分支:
git revert -m 1 <merge-commit-hash>
3. git stash — 暂存未提交的修改
场景:你正在改代码,突然需要切换分支处理紧急 bug,但当前改动还没写完不想 commit。
git stash # 把当前工作区和暂存区的改动暂存起来
git stash pop # 恢复最近一次 stash
git stash list # 查看所有 stash
git stash drop stash@{0} # 删除指定 stash
git stash 后: git stash pop 后:
工作区: (干净的旧版本) 工作区: (你的改动回来了)
暂存区: (空的) 暂存区: (你的改动)
版本库: (最新 commit) 版本库: (最新 commit)
4. git reflog — 救命稻草
reflog 记录了 HEAD 的所有移动。即使你 reset --hard 把 commit “弄丢了”,只要 reflog 还有记录,就能找回来。
场景:你误执行了 git reset --hard HEAD~5,5 个 commit 没了
$ git reflog
a1b2c3d (HEAD -> main) HEAD@{0} reset: moving to HEAD~5 ← 当前
f6e7d8c HEAD@{1} commit: feat: xxx ← 这就是丢失的 commit
...
恢复方法:
git reset --hard f6e7d8c # 把 HEAD 指回那个 commit
结论:reset --hard 不是 100% 不可逆,只要你还记得用 reflog。
5. 误删文件恢复
# 工作区误删了 hello.txt,从版本库恢复:
git restore hello.txt # Git 2.23+ 推荐
git checkout -- hello.txt # 老写法
# 文件已被 add 到暂存区,想从暂存区撤回到工作区(未删):
git restore --staged hello.txt
第四章:多人协作与企业实战
1. 远程仓库相关
git remote -v # 查看远程仓库地址
git remote add origin <url> # 添加远程仓库
git fetch origin # 拉取远程所有信息(不合并)
git pull origin main # 拉取并合并(= fetch + merge)
git push origin feature-x # 推送本地分支到远程
2. git fetch vs git pull 的区别
很多人把这两个混着用,结果分支莫名其妙多了些 commit。
fetch:只是把远程的提交"下载"到本地,不影响你的工作
远程 main: * c5
|
本地 main: * c4
↓ git fetch 后
本地 main: * c4 (main 指针没动)
↓ 但出现了一个 origin/main 指针
origin/main: * c5
pull:fetch + merge,本地 main 直接前进
本地 main: * c5 (HEAD -> main, origin/main) ← 已经合并了
3. git tag — 版本标签
git tag v1.0.0 # 给当前 commit 打标签
git tag -a v1.0.0 -m "release" # 附注标签(推荐)
git push origin v1.0.0 # 推送标签到远程
git tag -d v1.0.0 # 删除本地标签
常用于版本发布:v1.0.0、v1.1.0-beta。
4. git cherry-pick — 挑选特定 commit
场景:main 分支有个紧急修复,你想把那个 commit 单独拿到 release 分支上,但又不想合并整个分支。
从 feature 挑选 c3 到 main:
feature 分支: main 分支:
* c5 * c3' (HEAD) ← 新增,是 c3 的副本
| |
* c4 * c2
| |
* c3 ←── cherry-pick ──► * c1
|
* c2
|
* c1
用法:
git cherry-pick <commit-hash>
git cherry-pick <hash1> <hash2> # 一次挑多个
git cherry-pick --abort # 放弃 cherry-pick
5. 协作最佳实践
main(master)
│
├── develop(开发主分支)
│ ├── feature/login 功能开发
│ ├── feature/payment
│ └── feature/refund
│
└── hotfix/xxx 紧急修复
- main:只用来发布稳定版本,绝不直接提交
- develop:日常开发集成
- feature/xxx:每个新功能一个分支,完成后 merge 回 develop
- hotfix/xxx:紧急 bug 修复,从 main 拉,修复后同时合回 main 和 develop
- 合并必须经过 PR/MR 评审
第五章:救命命令速查
┌─────────────────────────────────────────────────────────────┐
│ 场景 命令 │
├─────────────────────────────────────────────────────────────┤
│ 撤销 git add git restore --staged <f> │
│ 撤销工作区修改 git restore <f> │
│ 修改最近一次 commit 信息 git commit --amend │
│ 找回 reset --hard 丢的 commit git reflog │
│ 撤销已 push 的 commit git revert <hash> │
│ 撤销未 push 的 merge git reset --hard HEAD~1 │
│ 撤销已 push 的 merge git revert -m 1 <hash> │
│ 暂时保存改动 git stash │
│ 恢复保存的改动 git stash pop │
│ 强制推送到远程(⚠️ 慎用) git push -f │
│ 放弃当前合并 git merge --abort │
│ 放弃当前 rebase git rebase --abort │
└─────────────────────────────────────────────────────────────┘
⚠️ 核心警告:
- 绝对不要在 master/main 上 force push(除非团队所有人都明确知道)
- 任何
reset --hard之前,先看一眼git status和git diff,确认没未保存的改动 - 已 push 的提交,优先用
revert,不要用reset
结尾:Git 命令全景图
最后给你一张图,把所有命令都串起来:
┌──────────────────────────────────────┐
│ 远程仓库 (origin) │
│ │
│ * c5 (origin/main) │
└───────────────┬──────────────────────┘
│ git fetch / git pull
│ git push
▼
┌─────────────┐ git add ┌─────────────┐ git commit ┌──────────────────────────────┐
│ │ ──────────► │ │ ───────────► │ 版本库 │
│ 工作区 │ │ 暂存区 │ │ │
│ (Working) │ │ (Stage) │ │ * c4 (HEAD -> main, │
│ │ ◄────────── │ │ │ │ feature) │
│ │ git restore │ │ │ * c3 │
└─────────────┘ └─────────────┘ │ * c2 │
▲ │ * c1 │
│ git stash / git checkout │ │
│ │ 分支:main、feature、hotfix │
└─────────────────────────────────────────────────└──────────────────────────────┘
历史查看:git log / git reflog
撤销安全:git revert
撤销危险:git reset(--soft / --mixed / --hard)
跨分支搬运:git cherry-pick / git rebase
记住这张图,你就掌握了 Git 的"心法"。剩下要做的,就是多敲、多踩坑、多用 reflog 救命。
真正的 Git 高手,不是记住了多少命令,而是脑子里随时能画出一张分支图,清楚每个指针指向哪里。
更多推荐




所有评论(0)