Git 的核心思想是记录文件系统的快照,而不是差异。每次提交(commit)都保存了项目所有文件在那一刻的完整状态(快照)。
理解快照操作,就是理解 工作区(Working Directory) → 暂存区(Staging Area / Index) → 版本库(Repository / Object Database) 之间的状态流转。
本文聚焦于所有与快照相关的 Git 命令,从基础到高级,每个命令都配有详细说明和实际示例。
一、核心概念:三个区域与文件状态
| 区域 | 说明 | 对应 Git 对象 |
|---|---|---|
| 工作区 | 电脑文件系统中看到的实际文件 | 普通文件 |
| 暂存区 | 一个临时存储区域,记录下一次提交要包含的内容 | index 文件 |
| 版本库 | .git 目录,存储所有提交的快照对象 | commit / tree / blob |
文件有四种状态:
- 未跟踪(Untracked):新文件,从未被 Git 记录过
- 已跟踪(Tracked):被 Git 管理的文件,又分为:
- 未修改(Unmodified):与上次提交一致
- 已修改(Modified):工作区被修改,但未暂存
- 已暂存(Staged):修改已加入暂存区,待提交
┌────────────┐ add ┌────────────┐ commit ┌────────────┐
│ 工作区 │ ────────→ │ 暂存区 │ ─────────→ │ 版本库 │
│ (Modified) │ │ (Staged) │ │ (Committed)│
└────────────┘ └────────────┘ └────────────┘
↑ │ │
└─────── restore ───────┘ │
(丢弃修改) │
┌────────────┘
↓
reset (移动 HEAD)
二、状态查看命令
1. git status – 查看当前快照状态
最常用的命令,显示工作区和暂存区的差异。
语法
git status [选项]
常用选项
| 选项 | 说明 |
|---|---|
-s / --short | 简洁格式输出 |
-b | 显示分支信息(常与 -s 连用) |
--ignored | 同时显示被忽略的文件 |
-v | 更详细,显示暂存区与 HEAD 的差异 |
示例
# 标准输出
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: README.md
new file: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: src/app.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
newfile.txt
# 简洁模式
$ git status -s
M README.md # 已暂存但未提交(左边 M)
A index.html # 新增已暂存
M src/app.js # 工作区修改未暂存(右边 M)
?? newfile.txt # 未跟踪
状态码含义(简洁模式)
| 符号 | 含义 |
|---|---|
?? | 未跟踪 |
A | 新增(已暂存) |
M | 修改(左侧=暂存区,右侧=工作区) |
D | 删除 |
R | 重命名 |
C | 复制 |
U | 未合并(冲突) |
2. git diff – 查看快照之间的差异
比较工作区、暂存区、版本库之间的内容变化。
语法
git diff [选项] [<路径>]
git diff --cached [选项] [<路径>]
git diff <提交1> <提交2>
常用比较场景
| 命令 | 比较对象 |
|---|---|
git diff | 工作区 vs 暂存区 |
git diff --cached / --staged | 暂存区 vs HEAD(最新提交) |
git diff HEAD | 工作区 vs HEAD |
git diff <commit> | 工作区 vs 指定提交 |
git diff <commit1> <commit2> | 两个提交之间 |
git diff <branch1> <branch2> | 两个分支的最新提交 |
常用选项
| 选项 | 说明 |
|---|---|
--stat | 只显示统计信息(修改的文件及行数) |
--name-only | 只显示文件名 |
--color-words | 按单词高亮差异(适合文本) |
--ignore-space-change | 忽略空格变化 |
-U<n> | 显示 n 行上下文(默认 3) |
--no-index | 比较两个非 Git 管理的文件 |
示例
# 查看工作区中哪些修改还未暂存
$ git diff
diff --git a/src/app.js b/src/app.js
index abc123..def456 100644
--- a/src/app.js
+++ b/src/app.js
@@ -10,7 +10,7 @@ function hello() {
- console.log("Hello")
+ console.log("Hello, World!")
}
# 查看暂存区与上次提交的差异(即即将提交的内容)
$ git diff --cached
# 查看工作区与上次提交的差异(包含已暂存和未暂存的全部修改)
$ git diff HEAD
# 只显示修改的文件名
$ git diff --name-only
README.md
src/app.js
# 显示统计信息
$ git diff --stat
README.md | 2 +-
src/app.js | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
# 比较两个提交
$ git diff abc123 def456
# 比较当前分支与 main 分支的差异
$ git diff main
# 只查看某个文件的差异
$ git diff README.md
# 忽略空白变化
$ git diff --ignore-space-change
3. git show – 显示某个提交的快照详情
展示指定提交的元数据和完整差异(即该提交引入的快照变化)。
语法
git show [选项] [<提交>]
常用选项
| 选项 | 说明 |
|---|---|
--stat | 只显示统计信息 |
--name-only | 只显示修改的文件 |
-s / --no-patch | 只显示提交信息,不显示差异 |
--format= | 自定义输出格式 |
示例
# 显示最新提交的快照变化
$ git show
# 显示指定提交
$ git show abc123
# 只显示该提交修改的文件列表
$ git show --name-only abc123
# 只显示提交消息和统计,不显示具体差异
$ git show -s --stat abc123
# 显示某个文件在某次提交中的内容(不是差异,而是该版本的文件)
$ git show abc123:README.md
# 显示某个标签对应的提交
$ git show v1.0
4. git log – 查看快照历史
虽然主要用于查看提交历史,但也能展示快照信息。
常用快照相关选项
| 选项 | 说明 |
|---|---|
-p / --patch | 显示每次提交的差异(即每个快照的变化) |
--stat | 显示每次提交的简略统计 |
--oneline | 单行简洁显示 |
--graph | 以 ASCII 图形显示分支结构 |
--pretty=format: | 自定义格式 |
示例
# 显示最近 2 次提交的详细快照差异
$ git log -p -2
# 显示每次提交修改的文件统计
$ git log --stat
# 单行显示,每条提交就是一个快照标识
$ git log --oneline
abc1234 (HEAD -> main) 修复登录验证
def5678 添加用户注册功能
三、暂存操作(工作区 → 暂存区)
5. git add – 将工作区的快照加入暂存区
语法
git add <文件/目录>...
常用选项
| 选项 | 说明 |
|---|---|
-A / --all | 添加所有修改、删除、新增的文件(整个工作区) |
-u / --update | 只添加已跟踪文件的修改/删除,不添加新文件 |
-p / --patch | 交互式选择部分修改块暂存(精细控制快照) |
-i / --interactive | 交互式添加界面 |
-f / --force | 强制添加被 .gitignore 忽略的文件 |
-n / --dry-run | 模拟添加,不实际执行 |
示例
# 添加单个文件
$ git add index.html
# 添加多个文件
$ git add index.html style.css
# 添加整个目录(递归)
$ git add src/
# 添加当前目录所有变更(包括删除和新增)
$ git add -A
# 或
$ git add .
# 只添加已跟踪文件的修改(不添加新文件)
$ git add -u
# 交互式选择部分修改块(精细化快照)
$ git add -p README.md
# 输出类似:
# diff --git a/README.md b/README.md
# @@ -1,3 +1,4 @@
# -Hello
# +Hello World
# Stage this hunk [y,n,q,a,d,e,?]?
# 选项:y-暂存,n-不暂存,e-手动编辑该块,s-分割成更小块
# 强制添加被忽略的文件
$ git add -f debug.log
# 预览会添加哪些文件(不实际添加)
$ git add -n
6. git restore --staged – 将文件移出暂存区(取消暂存)
语法
git restore --staged <文件>...
这是 Git 2.23 引入的命令,用于替代
git reset HEAD <file>的取消暂存功能。
示例
# 取消暂存某个文件(保留工作区的修改)
$ git restore --staged README.md
# 取消暂存所有文件
$ git restore --staged .
# 效果等同于旧的写法:git reset HEAD README.md
7. git reset --mixed – 移动 HEAD 并重置暂存区(但不改工作区)
这也是取消暂存的一种方式,但更强大。
# 将暂存区重置为 HEAD 的内容,但保留工作区的修改(默认行为)
$ git reset --mixed HEAD
# 等价于取消所有暂存
# 取消暂存特定文件(旧语法)
$ git reset HEAD README.md
四、提交操作(暂存区 → 版本库)
8. git commit – 将暂存区的快照永久存入版本库
每次 commit 会创建一个新的快照对象(commit + tree + blob)。
语法
git commit [-m "<消息>"]
常用选项
| 选项 | 说明 |
|---|---|
-m "<消息>" | 直接提供提交消息(不打开编辑器) |
-a / --all | 自动暂存所有已跟踪文件的修改,然后提交(跳过 git add) |
--amend | 修改上一次提交(替换快照或消息) |
--no-edit | 与 --amend 一起使用,不修改消息 |
-s / --signoff | 添加 Signed-off-by 签名 |
--allow-empty | 允许空提交(没有文件变更) |
-v | 在编辑器中显示差异 |
示例
# 标准提交(打开编辑器写消息)
$ git commit
# 带消息的提交
$ git commit -m "修复登录页面的样式问题"
# 多行消息
$ git commit -m "添加用户认证模块" -m "实现了 JWT 令牌验证"
# 跳过暂存区,直接提交已跟踪文件的修改(相当于先 add -u 再 commit)
$ git commit -a -m "更新配置文件和文档"
# 修改上一次提交(修正快照内容或消息)
# 先 add 遗漏的文件
$ git add forgotten-file.txt
$ git commit --amend --no-edit # 保持原消息,只追加新内容
# 只修改上一次提交的消息
$ git commit --amend -m "新的提交消息"
# 空提交(用于触发 CI)
$ git commit --allow-empty -m "触发构建"
# 添加签名
$ git commit -s -m "更新版权信息"
9. git commit --amend 的内部原理
实际上不是“修改”,而是用一个新的提交替换上一次提交的指针。原提交仍然存在(可通过 reflog 找回)。
# 假设当前历史
A -- B (HEAD)
# 执行 git commit --amend 后
A -- B' (HEAD)
\
B (仍然存在,但不可达)
五、撤销与回退快照
10. git restore – 丢弃工作区的修改(未暂存的快照恢复)
语法
git restore <文件>... # 丢弃工作区修改,恢复到暂存区或 HEAD 的状态
git restore --source=<提交> <文件> # 从指定提交恢复文件到工作区
示例
# 丢弃工作区中 README.md 的修改(不可恢复!)
$ git restore README.md
# 丢弃当前目录下所有工作区修改
$ git restore .
# 从某个提交恢复某个文件到工作区(同时覆盖工作区)
$ git restore --source=abc123 README.md
# 从上一个提交恢复文件
$ git restore --source=HEAD~1 src/app.js
11. git reset – 重置 HEAD 和暂存区/工作区(改变快照指针)
reset 命令用于移动当前分支的 HEAD 指针,并可选择性地重置暂存区和工作区。
三种模式
| 模式 | HEAD 指向 | 暂存区 | 工作区 | 典型用途 |
|---|---|---|---|---|
--soft | 改变 | 不变 | 不变 | 撤销提交,保留修改(修改仍在暂存区) |
--mixed (默认) | 改变 | 重置到目标提交 | 不变 | 撤销提交,保留修改在工作区(需重新 add) |
--hard | 改变 | 重置到目标提交 | 重置到目标提交 | 彻底丢弃提交及所有修改(危险) |
语法
git reset [--soft|--mixed|--hard] [<提交>]
示例
# 撤销最后一次提交,但保留修改在暂存区(相当于取消 commit)
$ git reset --soft HEAD~1
# 现在修改仍在暂存区,可直接再次 commit
# 撤销最后一次提交,并将修改移回工作区(默认)
$ git reset HEAD~1
# 或
$ git reset --mixed HEAD~1
# 彻底丢弃最近 3 次提交的所有更改(不可恢复!除非 reflog)
$ git reset --hard HEAD~3
# 取消暂存区的文件(保留工作区修改) – 等同于 git restore --staged
$ git reset HEAD README.md
# 将当前分支指向另一个提交,但不改变工作区(常用于移动分支起点)
$ git reset --soft abc123
⚠️ 警告:reset --hard 会丢弃工作区和暂存区的所有未提交修改。执行前请确认或使用 git stash。
12. git revert – 通过反向新提交来撤销快照
与 reset 不同,revert 不删除历史,而是创建一个反向快照(即撤销某次提交引入的变化)。适合公共分支。
语法
git revert <提交哈希>
示例
# 撤销某次提交(生成一个新提交)
$ git revert abc123
# 会打开编辑器,确认撤销消息,然后创建新提交
# 撤销最近一次提交
$ git revert HEAD
# 撤销但不自动提交(可批量撤销多个)
$ git revert -n abc123 def456
$ git commit -m "撤销 abc123 和 def456"
# 撤销一个合并提交(需指定主线)
$ git revert -m 1 merge-commit-hash
# 解决冲突后继续
$ git revert abc123
# 手动解决冲突
$ git add .
$ git revert --continue
13. git checkout (旧) / git switch (新) – 切换分支或恢复快照
部分快照恢复功能也可用 git checkout 实现,但 Git 2.23 后推荐分离用途。
恢复文件的旧方法
# 丢弃工作区修改(旧语法,等同于 git restore)
$ git checkout -- README.md
# 从某次提交恢复文件(旧语法)
$ git checkout abc123 -- src/app.js
推荐的新语法:使用 git restore 和 git switch 代替。
14. git clean – 删除未跟踪的快照文件(工作区)
删除那些从未被 Git 记录的文件(即不属于任何快照的文件)。
语法
git clean [选项]
常用选项
| 选项 | 说明 |
|---|---|
-n / --dry-run | 预览要删除的文件(安全) |
-f / --force | 强制删除(必须) |
-d | 同时删除未跟踪的目录 |
-x | 删除被 .gitignore 忽略的文件 |
-X | 只删除被 .gitignore 忽略的文件 |
示例
# 预览会删除哪些未跟踪文件
$ git clean -n
# 删除所有未跟踪文件(不包含目录)
$ git clean -f
# 删除未跟踪文件和目录
$ git clean -fd
# 删除包括被忽略的文件(如 .log, node_modules/)
$ git clean -fdx
# 只删除被 .gitignore 忽略的文件
$ git clean -fX
六、删除与移动快照中的文件
15. git rm – 从工作区和暂存区删除文件(并记录删除快照)
语法
git rm <文件>...
常用选项
| 选项 | 说明 |
|---|---|
--cached | 只从暂存区删除,保留工作区文件(停止跟踪) |
-f / --force | 强制删除(文件有未暂存修改时) |
-r | 递归删除目录 |
示例
# 删除文件并暂存删除操作
$ git rm old-file.txt
# 删除目录
$ git rm -r old-dir/
# 只从 Git 中移除跟踪,但保留工作区文件(适合停止跟踪配置文件)
$ git rm --cached config.local.json
# 强制删除(本地有修改且未暂存)
$ git rm -f important.txt
执行 git rm 后,该删除操作会进入暂存区,下次 commit 会生成一个文件被删除的新快照。
16. git mv – 移动或重命名文件(记录重命名快照)
语法
git mv <源文件> <目标文件>
说明
等价于执行:
mv old new
git add new
git rm old
示例
# 重命名文件
$ git mv index.html home.html
# 移动文件到子目录
$ git mv style.css assets/css/
# 移动并重命名
$ git mv old-name.txt src/new-name.txt
执行后,Git 会自动检测为重命名,并在 git status 中显示 renamed。
七、临时保存快照:Stash
17. git stash – 临时保存工作区和暂存区的快照(不提交)
当你需要切换分支但当前工作有未完成的修改时,可以使用 stash 把这些修改(包括暂存区)保存到一个栈中,恢复干净的工作区。
语法
git stash [push] [-m "<消息>"]
git stash list
git stash pop [stash@{n}]
git stash apply [stash@{n}]
git stash drop [stash@{n}]
git stash clear
常用子命令
| 命令 | 说明 |
|---|---|
git stash 或 git stash push | 保存当前工作区和暂存区的修改(不包括未跟踪文件) |
git stash push -u | 同时保存未跟踪的文件 |
git stash push -a | 保存所有文件(包括被忽略的) |
git stash list | 列出所有储藏 |
git stash pop | 应用最新的储藏并删除它 |
git stash apply | 应用最新的储藏(不删除) |
git stash drop | 删除指定的储藏 |
git stash clear | 删除所有储藏 |
git stash branch <分支名> | 从储藏创建新分支(自动应用并删除) |
git stash show | 显示储藏的差异摘要 |
示例
# 保存当前修改(自动生成消息)
$ git stash
Saved working directory and index state WIP on main: abc123 最后一次提交
# 保存并添加描述
$ git stash push -m "WIP: 登录验证逻辑未完成"
# 保存包括未跟踪的文件
$ git stash push -u
# 查看储藏列表
$ git stash list
stash@{0}: On main: WIP: 登录验证逻辑未完成
stash@{1}: On feature: 未完成的功能
# 应用最新的储藏(保留储藏)
$ git stash apply
# 应用并删除最新的储藏
$ git stash pop
# 应用指定的储藏
$ git stash apply stash@{1}
# 查看储藏的修改内容
$ git stash show stash@{0}
$ git stash show -p stash@{0} # 显示详细差异
# 删除指定的储藏
$ git stash drop stash@{0}
# 删除所有储藏
$ git stash clear
# 从储藏创建新分支(自动应用并删除储藏)
$ git stash branch new-feature stash@{0}
储藏的本质:
git stash 会创建两个(或三个,包括未跟踪文件)提交对象,分别对应当前暂存区的快照和工作区的快照,并重置工作区到 HEAD 的状态。这些提交不在任何分支上,可通过 git reflog 查看。
八、忽略文件:影响快照内容
18. .gitignore – 指定哪些文件不被 Git 跟踪
虽然不是命令,但是影响快照操作的关键配置文件。被忽略的文件不会被 git add 添加,也不会出现在 git status 的未跟踪列表中。
语法(在项目根目录或子目录创建 .gitignore 文件)
常用规则
# 注释
*.log # 忽略所有 .log 文件
/temp # 只忽略根目录下的 temp 文件/目录
build/ # 忽略 build 目录及其所有内容
!important.log # 不忽略 important.log(即使前面有 *.log)
*.class # 忽略所有 .class 文件
示例
# 生成一个典型的 Node.js 项目 .gitignore
$ cat > .gitignore << EOF
node_modules/
.env
*.log
dist/
.DS_Store
EOF
# 将 .gitignore 加入暂存区并提交
$ git add .gitignore
$ git commit -m "添加 .gitignore"
注意:如果文件已经被 Git 跟踪,.gitignore 不会自动停止跟踪。需要先执行:
$ git rm --cached <file>
九、高级快照操作
19. git add -p – 部分暂存(精细控制快照内容)
允许只暂存文件中的某些修改块(hunk),而不是整个文件。这是精细控制快照内容的强大工具。
示例
$ git add -p src/app.js
# Git 会逐个显示修改块,并询问操作:
# y - 暂存此块
# n - 不暂存此块
# q - 退出
# a - 暂存此文件剩余所有块
# d - 不暂存此文件剩余所有块
# s - 将当前块分割成更小的块
# e - 手动编辑当前块
# ? - 帮助
典型场景:一个文件中有多处修改,只想提交其中一部分。
20. git commit --amend – 修正上一个快照
前面已介绍。可以理解为用一个新的快照替换上一个快照。
21. git restore -p – 交互式丢弃工作区修改
类似 git add -p,但用于丢弃修改。
$ git restore -p README.md
# 交互式选择要丢弃的修改块
22. git reset -p – 交互式重置暂存区
$ git reset -p HEAD
# 选择要从暂存区移除的修改块
23. git cherry-pick – 复制其他分支的快照到当前分支
从一个或多个现有提交中提取快照变化,应用到当前分支。
语法
git cherry-pick <提交哈希>...
示例
# 将另一个分支的某个提交应用到当前分支
$ git cherry-pick abc123
# 复制多个提交
$ git cherry-pick abc123 def456
# 只应用更改,不自动提交(便于合并多个 cherry-pick)
$ git cherry-pick -n abc123
$ git commit -m "手动提交"
# 处理冲突后继续
$ git cherry-pick abc123
# 解决冲突
$ git add .
$ git cherry-pick --continue
24. git rebase -i – 交互式重写快照历史
可以重新排序、合并、删除、修改提交(快照)。这是 Git 最强大的历史重写工具。
示例
# 对最近 3 次提交进行交互式变基
$ git rebase -i HEAD~3
# 打开的编辑器中,你会看到类似内容:
pick abc123 添加登录功能
pick def456 修复登录bug
pick 789xyz 优化登录样式
# 可以修改命令:
# pick - 保留该提交
# reword - 保留快照,但修改提交消息
# edit - 保留快照,但停下来允许修改内容
# squash - 将该快照合并到前一个快照中
# fixup - 类似 squash,但丢弃该提交的消息
# drop - 删除该提交
# 保存退出后,Git 会按指令重写历史
注意:不要对已经推送到公共仓库的提交执行 rebase,否则会给协作者带来困扰。
十、快照操作组合示例
场景1:放弃所有本地修改(回到最新提交的干净快照)
# 丢弃工作区和暂存区的所有修改
$ git reset --hard HEAD
# 删除未跟踪的文件和目录
$ git clean -fd
场景2:撤销最后一次提交,但保留修改在工作区
$ git reset HEAD~1
# 现在修改回到工作区,可以重新编辑后再次 add/commit
场景3:修改上一次提交的快照(追加文件或修改内容)
# 修改文件或添加新文件
$ echo "new content" >> README.md
$ git add README.md
# 将新内容合并到上一次提交
$ git commit --amend --no-edit
场景4:将某个文件恢复到指定历史快照
# 方法1:使用 restore
$ git restore --source=abc123 README.md
# 方法2:使用 checkout(旧)
$ git checkout abc123 -- README.md
# 方法3:直接查看并重定向
$ git show abc123:README.md > README.md
场景5:只暂存文件中的部分修改(精细快照)
$ git add -p src/app.js
# 交互选择要暂存的块
$ git commit -m "只提交了部分修改"
场景6:临时保存当前快照,去做其他事,然后恢复
$ git stash push -m "WIP"
$ git checkout other-branch
# 做其他工作...
$ git checkout original-branch
$ git stash pop
场景7:合并多个提交为一个快照(压缩历史)
$ git rebase -i HEAD~4
# 将后三个提交的 pick 改为 squash 或 fixup
# 保存后编辑合并后的提交消息
十一、快照相关配置
git config 对快照操作的影响
# 设置默认提交消息模板
$ git config --global commit.template ~/.gitmessage.txt
# 设置默认编辑器(用于提交消息)
$ git config --global core.editor "code --wait"
# 让 git diff 显示颜色
$ git config --global color.ui auto
# 设置别名简化快照操作
$ git config --global alias.st status
$ git config --global alias.ci commit
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.unstage 'restore --staged'
$ git config --global alias.discard 'restore'
$ git config --global alias.last 'log -1 HEAD'
十二、快照操作速查表
| 操作 | 命令 | 说明 |
|---|---|---|
| 查看状态 | git status -s | 简洁查看工作区/暂存区状态 |
| 查看差异 | git diff | 工作区 vs 暂存区 |
| 查看暂存区差异 | git diff --cached | 暂存区 vs HEAD |
| 查看工作区 vs HEAD | git diff HEAD | 所有未提交修改 |
| 添加文件到暂存区 | git add <file> | 工作区 → 暂存区 |
| 交互式添加 | git add -p | 精细控制快照块 |
| 取消暂存 | git restore --staged <file> | 暂存区 → 工作区(保留修改) |
| 提交 | git commit -m "msg" | 暂存区 → 版本库 |
| 提交所有已跟踪修改 | git commit -a -m "msg" | 跳过 add |
| 修改上一次提交 | git commit --amend | 替换最新快照 |
| 丢弃工作区修改 | git restore <file> | 工作区 → 暂存区/HEAD |
| 彻底回退到指定提交 | git reset --hard <commit> | 危险!丢弃所有 |
| 撤销提交但保留修改 | git reset --soft HEAD~1 | 撤销 commit |
| 撤销提交并取消暂存 | git reset HEAD~1 | 撤销 commit 和 add |
| 安全撤销提交 | git revert <commit> | 生成反向新提交 |
| 删除文件 | git rm <file> | 工作区+暂存区删除 |
| 停止跟踪但保留文件 | git rm --cached <file> | 只从暂存区删除 |
| 移动/重命名 | git mv <old> <new> | 记录重命名快照 |
| 临时保存 | git stash push -m "msg" | 保存当前快照 |
| 恢复并删除暂存 | git stash pop | 应用最新储藏 |
| 删除未跟踪文件 | git clean -fd | 清理工作区 |
| 查看提交快照 | git show <commit> | 显示提交的差异 |
| 查看历史快照 | git log -p -2 | 显示最近2次提交的差异 |
结语
Git 的快照模型是其强大和优雅的根源。理解工作区、暂存区、版本库之间的数据流动,就能掌握所有快照操作的本质。每个命令都是在移动或比较不同区域之间的快照内容。
建议在日常工作中多使用 git status、git diff 和 git add -p 来精细控制快照内容,避免一次性提交大量无关修改。对于历史重写操作(如 rebase -i, reset --hard),请谨慎使用,并确保重要数据已备份或已推送。
不断实践,你会越来越得心应手。