掌握 git stash 的用法,学会临时保存工作现场、切换分支处理紧急事务,再回来无缝继续开发。

Stash — 给你的代码按一个暂停键

正在开发到一半,突然收到通知要修一个线上 Bug。代码写到一半不能 commit,又不想丢失进度,怎么办?

git stash 把你的工作现场临时存起来,处理完别的事再一键恢复。


一、什么是 Stash?

Stash 就像一个临时抽屉:把桌面上正在处理的文件暂时塞进去,桌面清空了,需要的时候再拿出来继续。

1
2
3
4
5
修改代码 ──→ git stash ──→ 抽屉(暂存栈)

处理其他事

git stash pop ──→ 代码回来了

典型场景

  • 开发到一半,需要切分支修 Bug
  • 代码还没写完,不想 commit 半成品
  • 临时切到另一个分支验证一个想法

二、基本操作

暂存当前修改

1
git stash

执行后,工作区和暂存区的修改会被保存,代码回到干净状态:

1
2
3
4
5
6
7
8
9
10
11
12
# 暂存前
git status
# modified: src/login.js
# modified: src/style.css

# 暂存
git stash
# Saved working directory and index state WIP on main: a1b2c3d feat: ...

# 暂存后
git status
# nothing to commit, working tree clean ← 干净了!

暂存并附带说明(推荐)

1
git stash save "正在开发登录功能,未完成表单验证"
推荐

加上 save 说明,方便后面多个 stash 时区分哪个是哪个。

恢复暂存

1
2
3
4
5
# 恢复最近一次暂存,并从栈中删除
git stash pop

# 恢复但不删除(保险起见)
git stash apply

三、管理多个 Stash

Stash 是一个栈结构(后进先出),可以存多个暂存。

查看所有 Stash

1
2
3
4
5
6
git stash list

# 输出示例:
# stash@{0}: WIP on main: a1b2c3d feat: 开发登录功能
# stash@{1}: On main: 正在修首页样式
# stash@{2}: WIP on develop: e4f5g6h fix: 修复接口报错

恢复指定的 Stash

1
2
3
4
5
# 恢复第 2 个暂存(索引从 0 开始)
git stash pop stash@{1}

# 只恢复不删除
git stash apply stash@{1}

删除指定的 Stash

1
2
# 删除第 2 个
git stash drop stash@{1}

清空所有 Stash

1
git stash clear

clear 不可恢复:清空后无法找回,执行前确认所有 stash 都不再需要。


四、常用选项

包含未跟踪的新文件

默认 git stash 只暂存已跟踪文件的修改,新创建的未跟踪文件不会保存:

1
2
3
4
5
# -u:同时暂存未跟踪的文件
git stash -u

# --include-untracked(同上,完整写法)
git stash --include-untracked

包含已忽略的文件

1
2
# -a:暂存所有文件(包括 .gitignore 忽略的)
git stash -a

选项速查表

选项缩写作用
save "说明"暂存并附带说明
--include-untracked-u包含未跟踪的新文件
--all-a包含所有文件(含忽略的)
--keep-index-k保留暂存区的内容不动
--patch-p交互式选择哪些改动要暂存

五、查看 Stash 的内容

查看暂存了哪些文件

1
2
3
4
5
6
# 查看最近一次 stash 改了哪些文件
git stash show

# 输出:
# src/login.js | 12 +++++++++---
# src/style.css | 5 ++++-

查看具体代码差异

1
2
3
4
5
# -p:显示详细的 diff
git stash show -p

# 查看指定 stash 的差异
git stash show -p stash@{1}

六、从 Stash 创建分支

如果你在 main 分支上 stash 了代码,想在一个新分支上恢复:

1
2
# 基于 stash 创建新分支,并自动恢复暂存内容
git stash branch feature/login stash@{0}

这等于以下操作的组合:

1
2
git checkout -b feature/login       # 创建新分支
git stash pop stash@{0} # 恢复暂存
适用场景

在错误的分支上开发了一段代码,用 stash branch 可以把这些代码搬到正确的分支上。


七、Stash 冲突处理

恢复 stash 时,如果暂存的修改和当前代码有冲突,处理方式跟 merge 冲突一样:

1
2
3
4
5
6
7
8
9
10
11
# 恢复 stash
git stash pop

# 如果冲突,Git 会提示
# CONFLICT (content): Merge conflict in src/login.js

# 手动解决冲突标记
vim src/login.js

# 标记已解决
git add src/login.js

注意:stash 冲突恢复后,stash 不会自动从栈中删除(因为它没有成功 pop)。需要手动 git stash drop 清理。


八、实战:完整的 Stash 工作流

场景:开发到一半要修线上 Bug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 正在 feature/login 分支上开发...
# 突然收到紧急 Bug 通知

# 1. 暂存当前工作
git stash save "登录功能开发中 - 表单验证未完成"

# 2. 切到 hotfix 分支
git checkout -b hotfix/payment-bug origin/main

# 3. 修复 Bug
vim src/payment.js
git add src/payment.js
git commit -m "fix: 修复支付金额计算错误"
git push origin hotfix/payment-bug

# 4. 切回功能分支
git checkout feature/login

# 5. 恢复工作现场
git stash pop

# 继续开发,一切还在!

场景:把代码搬到正确的分支

1
2
3
4
5
6
7
8
9
# 不小心在 main 上写了功能代码

# 1. 暂存
git stash

# 2. 从 stash 创建新分支
git stash branch feature/search

# 代码已经在新分支上了,继续开发

总结:Stash 速查卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──────────────────────────────────────────────────────────┐
│ Git Stash 速查 │
├────────────────┬─────────────────────────────────────────┤
│ 暂存修改 │ git stash / git stash save "说明" │
│ 暂存含新文件 │ git stash -u │
├────────────────┼─────────────────────────────────────────┤
│ 查看暂存列表 │ git stash list │
│ 查看暂存内容 │ git stash show -p [stash@{N}] │
├────────────────┼─────────────────────────────────────────┤
│ 恢复并删除 │ git stash pop [stash@{N}] │
│ 恢复不删除 │ git stash apply [stash@{N}] │
│ 删除指定暂存 │ git stash drop stash@{N} │
│ 清空所有暂存 │ git stash clear │
├────────────────┼─────────────────────────────────────────┤
│ 从暂存建分支 │ git stash branch <分支名> stash@{N} │
└────────────────┴─────────────────────────────────────────┘