介绍
git stash 中文叫 储藏/暂存现场,功能:
把 工作区未提交的修改(已修改、新增未track文件可配置) 临时保存到本地独立储藏栈,清空当前工作目录,回到干净、无改动的分支状态;
后续随时取出储藏的修改恢复,不产生commit、不污染提交记录,只存在本地,不会推送到远程仓库。
存储范围说明
- 默认储藏:已被git追踪的文件(修改、删除),不储藏未跟踪新文件、忽略文件
git stash -u:一并储藏未跟踪新文件git stash -a:储藏所有文件(含.gitignore忽略的文件,慎用)
储藏栈结构
stash是栈结构,后进先出:
- 每次执行
git stash会新增一条储藏记录,编号stash@{0}(最新)、stash@{1}(上一次)…… - 不会覆盖旧储藏,可以同时存多套临时代码现场。
常用命令
# 1. 保存当前所有追踪文件改动到储藏栈
git stash
# 带备注,方便区分多份储藏(推荐)
git stash save "备注:修复登录页面临时改动"
# 储藏+包含未跟踪新文件
git stash -u save "备注"
# 2. 查看所有储藏列表
git stash list
# 3. 查看某条储藏的改动详情
git stash show stash@{0}
# 完整diff展示
git stash show -p stash@{0}
# 4. 恢复储藏(两种方式)
# pop:取出并删除栈顶储藏(用完即销毁)
git stash pop stash@{0}
# apply:取出但保留储藏记录(需要可重复恢复)
git stash apply stash@{0}
# 5. 删除储藏
# 删除指定储藏
git stash drop stash@{1}
# 清空所有储藏
git stash clear
应用场景
场景1:开发一半,切换分支改bug(最常用)
你在 feature/login 分支写登录页逻辑,代码写到一半、逻辑不完整,不能commit提交(提交会产生半成品脏提交,污染分支历史);
此时线上/测试环境爆出紧急bug,需要立刻切到 main 分支修复。
解决方案
- 储藏当前半成品代码
git stash save "登录页开发到一半,临时切分支修bug" - 工作区清空,干净切换分支
git checkout main # 修复bug、提交、推送 git add . && git commit -m "fix: 修复支付报错" git push - bug修复完切回开发分支,恢复之前写一半的代码
git checkout feature/login git stash pop # 此时之前未写完的代码全部恢复,继续开发
优势对比
不用临时提交半成品commit,后续不用git reset删脏提交,分支历史整洁。
场景2:临时测试其他分支功能,不想丢弃本地改动
当前分支有大量本地调试改动,想切到release分支看线上代码效果,但不想删掉本地调试代码;
又不想commit、不想复制文件备份。
操作
git stash -u save "本地调试临时代码"
git checkout release
# 查看、测试线上代码
# 测试完切回,恢复调试代码
git checkout 原分支
git stash pop
场景3:同分支临时切换不同方案,多套代码临时存档
同一个功能你写了两套实现方案,需要来回对比调试,不想互相覆盖;
不适合提交多个commit,只想本地临时保存两套代码。
操作
写完方案A,储藏
git stash save "方案A:接口直连实现"清空工作区,写方案B,再储藏
git stash save "方案B:缓存封装实现"查看所有储藏
git stash list stash@{0}: On feature: 方案B:缓存封装实现 stash@{1}: On feature: 方案A:接口直连实现切换查看方案A(apply不删除储藏,可反复切换)
git stash apply stash@{1} # 对比完成后,恢复方案B git stash apply stash@{0}
场景4:拉取远程代码冲突,但本地代码未完成无法提交
本地正在开发,远程main分支有新提交,执行git pull提示冲突;
本地代码半成品不能commit,直接pull会覆盖/冲突无法处理。
流程
# 1. 临时储藏本地改动
git stash save "开发中代码,拉取远程前暂存"
# 2. 拉取远程最新代码(此时工作区干净,无冲突干扰)
git pull
# 3. 恢复本地代码,自动合并本地改动与远程更新,解决冲突
git stash pop
# 出现冲突手动解决,继续开发
场景5:临时丢弃当前改动,但后续可能需要找回
写了一堆调试代码,测试后发现方案完全不可行,想清空工作目录;
但不确定后续会不会复用这段调试逻辑,不想直接git checkout .永久删除。
方案
# 储藏保存,工作区恢复干净
git stash save "废弃调试代码,备用"
# 后续如果需要查看,随时show/apply
git stash show -p stash@{0}
# 确认彻底无用再删除
git stash drop stash@{0}
场景6:跨分支复用一段临时代码(不用cherry-pick)
在A分支写了一段通用工具函数,想复制到B分支使用,但不想提交commit再cherry-pick。
流程
# A分支储藏代码
git stash save "通用工具类函数"
# 切到B分支
git checkout B
# 取出储藏代码到当前分支
git stash pop
# 按需保留/删除不需要的代码,直接使用
stash pop 和 apply 关键区别
git stash pop- 取出储藏改动应用到当前分支;
- 成功应用后直接删除这条储藏记录;
- 适合:用完不需要再复用的临时代码。
git stash apply- 取出改动,但储藏记录仍然保存在栈中;
- 可多次在不同分支、不同时间重复恢复;
- 适合:多套方案来回切换、代码需要反复查看。
常见坑与注意事项
默认不储藏未跟踪新文件
新建文件没add到暂存区,直接git stash不会保存,丢失风险;
解决方案:统一用git stash -u。切换分支后apply/pop储藏,可能产生跨分支冲突
储藏代码是基于原分支文件结构,切换其他分支恢复时文件差异大会冲突,手动解决即可。stash仅存在本地仓库
无法push到远程,换电脑、删仓库、克隆新仓库后储藏记录全部消失;重要临时代码建议commit提交。stash clear 会一次性清空所有储藏,无法找回,谨慎执行。
储藏后重启电脑、关闭git客户端不丢失,储藏持久保存在本地.git目录。