git stash 默认只暂存已跟踪且被修改的文件,不包括新增未跟踪或忽略文件;需用 -u 或 -a 显式包含;stash 不清空暂存区,切换分支前应确保工作区和暂存区均干净;pop 冲突时 stash 仍保留,需手动解决后 drop;推荐用 stash push 替代以支持消息和路径限制。

stash 命令到底存了什么?
Git git stash 默认只暂存「已跟踪(tracked)但被修改」的文件,**不会保存新增的未跟踪文件(untracked)或忽略文件(.gitignore 中的)**。如果你刚写了新模块、加了配置文件但还没 git add,直接 git stash 后切换分支,这些文件会原地留下——既不在工作区干净状态里,也不在 stash 记录中,极易误删或遗漏。
实操建议:
- 确认当前新增文件是否需要保留:用
git status查看Untracked files区域 - 如需一并暂存,必须加
-u(--include-untracked):git stash -u - 若还涉及忽略文件(比如本地 .env),得再加
-a(--all),但慎用——可能把不该提交的敏感内容也塞进 stash
切换分支前必须检查 stash 是否干净
执行 git stash 后 Git 不会自动清空暂存区(index),也就是说,如果之前有 git add 过部分改动,那些「暂存的变更」仍保留在 index 中。此时切分支,新分支会带着旧的暂存状态,极大概率导致 git commit 时提交了不属于当前分支的代码。
正确做法是确保「工作区 + 暂存区」都干净再切分支:
- 运行
git stash --keep-index可只 stash 工作区改动,保留暂存区 —— 适合你只想临时切走、回头继续 commit 当前暂存内容的场景 - 更推荐一步到位:
git stash -u && git stash pop后立刻git status确认输出为nothing to commit, working tree clean - 别信「我刚 stash 了就肯定干净」——多看一眼
git status总比在紧急分支上错提代码强
stash pop 失败后如何安全恢复原始更改
当你在目标分支执行 git stash pop 时,如果发生冲突(比如 stash 里的修改和当前分支已有改动重叠),Git 会中断弹出并标记冲突文件,但**stash 记录并未自动删除**。此时 git stash list 仍能看到它,而工作区处于半合并状态。
常见错误是强行 git stash drop 或直接 git reset --hard,结果把原始修改彻底丢掉。
稳妥操作顺序:
- 先用
git status确认哪些文件冲突,用git diff看 stash 里改了什么 - 手动解决冲突后,运行
git add标记为已解决 - 再执行
git stash drop删除该 stash(不是pop,避免重复应用) - 如果决定放弃这次恢复,直接
git stash show -p查看内容,然后git stash drop即可 —— stash 本身不依赖分支,删了也不影响其他分支
用 stash push 替代传统 stash 更可控
git stash 是 git stash push 的简写,但后者支持更多关键参数,尤其适合多人协作或长期暂存场景。
比如紧急修复分支要切多次,你可能需要区分不同 stash:
- 加
-m "fix/login-api-timeout"写明用途,避免git stash list里全是WIP on main...这种无意义描述 - 指定路径限制暂存范围:
git stash push -m "temp: config only" config/*.yml,避免误 stash 整个前端构建产物 - 想暂存但不立即切换?
git stash push --keep-index配合git checkout -b hotfix/timeout,比先 stash 再 checkout 更原子
注意:git stash apply 不会删 stash,git stash pop 才会——但 pop 失败时 stash 依然保留,这点很多人会忽略。










