Git 暂存操作速查表 — save / pop / apply / drop / list / show / branch
Git stash 就像是未提交工作的'存档点'。它可以临时搁置你的更改,让你能够切换分支、拉取上游更新或重新开始——然后稍后恢复你的工作。本指南涵盖了从基本的 stash/pop 到高级操作(如暂存未跟踪文件、部分暂存以及从暂存创建分支)的所有内容。
快速参考表
| 操作 | 命令 | 场景 |
| 暂存所有已跟踪更改 | git stash | 快速保存,切换分支 |
| 带备注暂存 | git stash push -m "msg" | 记录你保存了什么 |
| 同时暂存未跟踪文件 | git stash push -u | 包含新文件 |
| 暂存所有(含忽略文件) | git stash push -a | 完全清理工作区 |
| 暂存指定文件 | git stash push -m "msg" | 选择性保存 |
| 交互式逐块暂存 | git stash push -p | 部分暂存 |
| 列出所有 stash | git stash list | 查看保存的内容 |
| 查看 stash 的 diff | git stash show -p [stash@{n}] | 检查暂存的更改 |
| 恢复最新并保留 | git stash apply | 恢复但不从列表删除 |
| 恢复并删除(一次性) | git stash pop | 默认恢复流程 |
| 恢复指定 stash | git stash apply stash@{2} | 选择特定的保存点 |
| 删除指定 stash | git stash drop stash@{2} | 清理旧的 stash |
| 删除所有 stash | git stash clear | ⚠️ 不可撤销 |
| 从 stash 创建分支 | git stash branch [stash@{n}] | 在新分支上恢复 |
git stash push — 保存工作
git stash push(或简写 git stash)将修改过的已跟踪文件保存到新的 stash 条目中,并将工作目录恢复到上次提交的状态。
``bash
# 基本保存——只保存已跟踪文件
git stash
# 带描述信息保存 git stash push -m "WIP: 重构认证中间件"
# 同时暂存未跟踪文件 git stash push -u
# 暂存所有文件,包括 .gitignore 中的 git stash push -a
# 只暂存特定文件 git stash push -m "配置调整" src/config.ts
# 交互式暂存——逐块选择 git stash push -p
# 保留已暂存更改,只暂存未暂存的修改
git stash push --keep-index
`
> 提示: git stash push 是现代的功能完整形式。旧的 git stash save 命令已弃用。
### 参数详解
| 参数 | 作用 |
| (无) | 只暂存已跟踪文件 |
-u / --include-untracked | 包含未跟踪文件 |
-a / --all | 同时包含忽略文件 |
-m / --message | 添加标识标签 |
-p / --patch | 交互式逐块选择 |
--keep-index | 保留已暂存的更改 |
git stash list / show — 查看 Stash
`bash
# 列出所有 stash 条目
git stash list
# 显示详细信息 git stash list --format="%gd: %gs (%cr)"
# 显示 stash 的变更摘要(diffstat) git stash show stash@{0}
# 显示 stash 的完整 diff git stash show -p stash@{2}
# 显示最新 stash 的 diff
git stash show -p
`
git stash list 输出使用 stash@{n} 标记:
`
stash@{0}: On main: WIP: 重构认证中间件
stash@{1}: On feature/login: 修复登录表单验证
stash@{2}: On develop: 调试日志清理
`
Stash 堆栈是 LIFO(后进先出)的,stash@{0} 始终是最新的。
git stash pop / apply — 恢复更改
### git stash pop — 恢复并删除
应用 stash 并从列表中删除。这是标准的一次性工作流。
`bash
# 应用最新 stash 并删除
git stash pop
# 应用指定 stash 并删除
git stash pop stash@{1}
`
如果在 pop 过程中出现冲突,stash 条目不会被删除——它会被保留以便你解决冲突后重试。
### git stash apply — 恢复并保留
应用 stash 但保留在列表中。适合需要多次恢复同一更改的场景(如将一个修复应用多个分支)。
`bash
# 应用最新 stash,保留
git stash apply
# 应用指定 stash,保留
git stash apply stash@{3}
`
| 特性 | git stash pop | git stash apply |
| 恢复更改 | ✅ | ✅ |
| 从列表删除 | ✅ | ❌ |
| 一次性恢复 | ⭐⭐⭐⭐⭐ | ❌ |
| 多分支复用 | ❌ | ⭐⭐⭐⭐⭐ |
| 冲突处理 | 保留 stash | 保留 stash |
git stash drop / clear — 清理
`bash
# 删除指定 stash
git stash drop stash@{1}
# 删除最新 stash git stash drop
# 清空所有 stash(⚠️ 不可撤销)
git stash clear
`
> ⚠️ 警告: git stash clear 永久删除所有 stash 条目。没有 git stash undo 这种操作。如果不确定,请逐个删除。
git stash branch — 在新分支上恢复
如果你在一个分支上暂存了更改,而工作树已经有了很大变化,直接应用 stash 可能产生严重冲突。git stash branch 会在创建 stash 时的 commit 处创建一个新分支。
`bash
# 从最新 stash 创建分支
git stash branch fix/login-issue
# 从指定 stash 创建分支
git stash branch fix/login-issue stash@{1}
`
这个命令:
1. 检出 stash 基于的 commit
2. 在该 commit 上创建新分支
3. 将 stash 应用到该分支上
4. 删除 stash 条目(类似 pop)
这是恢复旧 stash 的最安全方式——当 stash 不再能干净地应用到当前 main 时。
实用工作流示例
### 示例 1:中断——紧急切换到其他分支
`bash
# 在 feature-x 上工作,但 main 上有紧急修复
git stash push -m "WIP: feature-x 进度"
git checkout main
# ... 修复 bug,提交,推送 ...
git checkout feature-x
git stash pop
`
### 示例 2:不提交就直接拉取
`bash
# 需要 git pull 但工作区不干净
git stash push -m "pull 前保存"
git pull --rebase
git stash pop
`
### 示例 3:为干净构建清理工作区
`bash
git stash push -u -m "构建前检查点"
./build.sh
git stash pop
`
### 示例 4:恢复无法干净应用的旧 stash
`bash
git stash list
# stash@{4}: On adjust-pricing: 价格计算重构
git stash branch rework-pricing stash@{4}
# 现在在原始 commit 的新分支上工作
`
### 示例 5:测试有无更改的对比
`bash
# 保存更改
git stash push -m "我的功能更改"
npm test # 测试时不包含你的更改
git stash pop
npm test # 测试时包含你的更改
`
### 示例 6:只暂存部分内容用于部分提交
`bash
git add src/app.ts # 暂存"安全"的更改
git stash push --keep-index # 暂存剩余的混乱工作
git commit -m "安全提交"
git stash pop # 恢复混乱的工作
`
常见问题排查
| 症状 | 原因 | 修复 |
git stash apply 冲突失败 | 工作树已分叉 | 使用 git stash branch 替代 |
git stash 没保存新文件 | 未跟踪文件被排除 | 使用 git stash push -u |
| 不小心清空了 stash | stash 列表现在为空 | 用 git stash list 确认;如果真没了就没了——养成定期 stash 的习惯 |
| 想查看 stash 内容但不应用 | 不确定内容 | git stash show -p stash@{n}` 查看完整 diff |
暂存操作(20)
| 命令 | 难度 | ||
|---|---|---|---|
git stash暂存当前工作区的更改 | 基础 | git stash | |
git stash pop应用最近的暂存并删除它 | 基础 | git stash pop | |
git stash list列出所有暂存 | 基础 | git stash list | |
git stash apply应用暂存但不删除它 | 基础 | git stash apply stash@{0} | |
git stash drop删除指定的暂存 | 基础 | git stash drop stash@{0} | |
git stash show显示暂存的更改摘要 | 基础 | git stash show stash@{0} | |
git stash branch从暂存创建新分支 | 中级 | git stash branch new-feature stash@{0} | |
git stash push -m暂存更改并添加描述消息 | 基础 | git stash push -m "WIP: login feature" | |
git stash push -u暂存更改时包含未跟踪的文件 | 中级 | git stash push -u -m "work in progress" | |
git stash push -a暂存所有文件(包括被忽略的文件) | 高级 | git stash push -a | |
git stash push -p交互式暂存(选择部分更改) | 高级 | git stash push -p | |
git stash push -k暂存未暂存的更改,保留已暂存的内容 | 中级 | git stash push -k | |
git stash show -p显示暂存的详细差异 | 中级 | git stash show -p stash@{0} | |
git stash clear删除所有暂存记录 | 中级 | git stash clear | |
git stash apply --index应用暂存并恢复暂存区状态 | 中级 | git stash apply --index stash@{0} | |
git stash pop --index弹出暂存并恢复暂存区状态 | 中级 | git stash pop --index stash@{0} | |
git stash list --format自定义格式列出暂存记录 | 高级 | git stash list --format='%C(yellow)%gd %C(reset)%s' | |
git stash push -S暂存已暂存的更改(只存暂存区) | 高级 | git stash push -S -m "stash staged only" | |
git stash -- <pathspec>暂存指定路径的更改 | 中级 | git stash push -m "config changes" -- config/ | |
git stash save暂存更改(传统语法) | 基础 | git stash save "WIP: refactoring auth module" |