🏠 首页 攻略 "Git Stash高级用法:从临时保存代码到多分支流转,一篇搞定"

"Git Stash高级用法:从临时保存代码到多分支流转,一篇搞定"

Git stash不只是临时存代码那么简单。本文覆盖stash save、apply/pop、命名存储、跨分支转移、清理管理,还有5个高频实战场景,让你的版本控制效率翻倍。

Git Stash不只是临时存代码

你是不是也这样用过 Git stash?

git stash          # 紧急切分支,先藏起来
git stash pop      # 回来再恢复

停。这就太浪费 stash 的能力了。

stash 是 Git 里被严重低估的功能。用好它,你能解决很多"尴尬切换"的场景,甚至用它来做跨分支的代码流转。

下面我把 stash 从基础到进阶全部捋一遍。全是实战,不整虚的。


一、stash 的基本操作:save vs pop vs apply

先搞清楚三个核心命令的区别。

git stash save(已废弃,了解即可)

老版本用 git stash save "描述" 来命名存储。现在官方已经不推荐了,替代方案在后面。

git stash push(现代写法)

git stash push -m "feature: 临时保存登录页修改"

pushsave 的现代替代品,支持 -m 加描述,也支持 -u 把 untracked 文件一起存。

git stash apply vs git stash pop

这是很多人搞混的地方。

命令从栈中移除?适用场景
git stash apply想恢复但不想丢原始记录
git stash pop恢复完就删掉,干净利落

简单记:需要保留记录用 apply,不需要用 pop。

git stash list — 查看存储列表

$ git stash list
stash@{0}: On main: 临时保存登录页修改
stash@{1}: On feature/ui: 表单验证改动
stash@{2}: WIP on main: a3f2b1c 修复bug

编号从 0 开始,0 是最新的。


二、5个高频实战场景

场景1:正在修bug,突然要切分支处理紧急需求

# 当前在 main 分支,改了3个文件还没 commit
git status
# modified: src/login.tsx
# modified: src/api/user.ts
# modified: tests/test_login.py

# 不用 commit,直接 stash
git stash push -m "login页未完成修改"

# 切分支处理紧急需求
git checkout hotfix/payment
# ... 处理紧急需求,commit,push

# 回到 main 继续
git checkout main
git stash pop
# 你的修改回来了,继续推进

场景2:多个 stash 之间切换

# 列出所有 stash
git stash list

# 恢复指定 stash(不按顺序)
git stash apply stash@{2}

# 恢复后再删除
git stash pop stash@{1}

场景3:只 stash 部分文件(而不是全部)

# 查看当前修改的文件
git status

# 交互式选择要 stash 的文件
git stash push -p

# 终端会一个个文件问你:"Stash this hunk? (y/n/a/d/s/?) "
# y = 存这个块, n = 跳过, a = 存全部, d = 删全部, s = 拆分

-p(patch)模式非常实用。比如你改了 A 文件和 B 文件,只想暂存 A 文件的部分改动,B 文件留着继续开发。

场景4:把 stash 转移到另一个分支

这是很多人不知道的技巧。stash 默认存在当前分支上,你想在其他分支用怎么办?

# 假设你在 feature 分支创建了 stash
git stash push -m "测试代码"

# 切到 main 分支
git checkout main

# 无法直接用 stash,因为 stash 关联的是 feature 分支的提交
# 解决方法:先 apply 再切分支
git checkout feature
git stash apply

# 现在有代码了,切到 main
git checkout main

# 合并或 cherry-pick 你想要的提交
git merge feature --no-ff

或者更优雅的方式——用 git stash branch 一步到位:

git stash branch temp-fix stash@{0}
# 这条命令会:
# 1. 基于 stash 创建时的分支创建新分支
# 2. 自动 apply stash 的内容
# 3. 把你切换到新分支

场景5:清理无用的 stash

# 清理所有已应用的 stash
git stash drop stash@{2}

# 清理超过1天的 stash
git stash clear

# 只保留最近的3个,其余全部删除
git stash list | tail -n +4 | cut -d: -f1 | xargs -I {} git stash drop {}

三、stash 的隐藏参数

-u:包含 untracked 文件

默认情况下,stash 不会存新建但未跟踪的文件。加上 -u

git stash push -u -m "连新建文件一起存"

相当于 git add . 然后再 stash。

-k:stash 和 working tree 都保留

git stash push -k -m "双份备份"

stash 之后,你的工作区改动不会被清空。适合你需要同时访问两份代码的场景。

–include-untracked:别名写法

-u 效果一样,看个人习惯。


四、常见坑和避坑指南

坑1:stash 后恢复出现冲突

git stash pop
# CONFLICT (content): Merge conflict in src/login.tsx

如果 stash 后主分支有其他提交,pop 时可能冲突。解决方法:

# 查看冲突详情
git diff

# 手动解决冲突
# 编辑文件,去掉 <<<< ==== >>>> 标记

# 解决后继续
git add src/login.tsx
git stash pop --continue

坑2:stash 太多忘了清理

$ git stash list
stash@{0}: ...
stash@{1}: ...
stash@{2}: ...
stash@{3}: ...
stash@{4}: ...
stash@{5}: ...

五个以上的 stash 就是负担。定期清理:

# 查看 stash 占用空间
git fsck --no-reflog | grep dangling | wc -l

# 清理所有已应用的 stash
git stash clear

坑3:在 detached HEAD 状态下 stash

git checkout v1.2.0
git stash push -m "在tag上修改"
# 警告:stash 在 detached HEAD 状态下行为可能不稳定

不建议在 detached HEAD 上做 stash。先创建一个临时分支:

git checkout -b temp-v1.2.0
git stash push -m "安全做法"

五、stash 最佳实践总结

实践说明
永远加 -m 描述方便后续查找和识别
push 代替 save更灵活,支持更多选项
用完即清别攒一堆 stash 不管
大改动先 commitstash 适合临时保存,不适合长期存档
跨分支用 branch 命令比手动 apply 更可靠

写在最后

Git stash 不是"应急按钮",而是一个可以精细控制的工作流工具。

下次你再想 git stash 不加任何参数的時候,停下来想想——你真的需要描述吗?需要包含 untracked 文件吗?还是只想 stash 部分改动?

多花3秒想清楚,后面能省半小时。


觉得有用?试试在你的项目里用一次 git stash push -p,看看它怎么帮你精准选择要暂存的代码块。