直接说结论:git stash save 和 git stash push 功能几乎一样,但 save 已被官方标记为"废弃(deprecated)",现在一律推荐用 push。
两者的核心区别在于 参数解析方式 ,push 更安全、更严格。
一、用法对比(重点看区别)
1、基本用法(两者完全等价)
# 旧写法
git stash save "修复登录bug"
# 新写法(推荐)
git stash push -m "修复登录bug"
如果只是存全部改动,这俩没区别,但
push的-m更符合 Git 其他命令的习惯(如commit -m)。
2、指定文件路径(这是最大的坑!)
这是你刚才问的"只 stash 个别文件"的场景,必须用 push:
# ✅ 正确写法(推荐)
git stash push -m "暂存配置" -- config.yml
# ❌ 危险写法(不推荐,容易出错)
git stash save "暂存配置" config.yml
为什么?
-
git stash push强制使用--分隔符,明确区分"消息"和"文件路径",永远不会混淆。 -
git stash save没有 --分隔符。Git 会尝试把后面的参数解析为消息,如果文件名看起来像参数(比如以-开头),或者解析逻辑有歧义,就会报错或产生非预期行为。
3、交互式 Stash(部分代码)
# 两者都支持 -p
git stash save -p
git stash push -p
功能一样,但 push 是未来的标准。
二、为什么 Git 官方要废弃 save?
在 Git 2.16 版本之后,官方引入了 git stash push 来取代 save,主要原因是 API 一致性 和 安全性:
-
参数歧义 :
save命令会把第一个非选项参数之后的所有内容都当成 stash 消息,除非你非常小心,否则很容易把文件名误当成消息,或者把消息误当成文件。 -
命令统一性 :Git 的大多数命令(如
git commit -m,git tag -m)都使用-m来指定消息。push沿用了这一风格,降低了学习成本。 -
路径规范(Pathspec) :
push强制要求--来分隔消息和路径,这是 Git 处理文件路径的标准方式,避免了各种边缘情况的 Bug。
三、速查对照表
| 需求 | git stash save (旧/不推荐) |
git stash push (新/推荐) |
|---|---|---|
| 存全部改动 | git stash save "msg" |
git stash push -m "msg" |
| 存指定文件 | git stash save "msg" -- file (容易混淆) |
git stash push -m "msg" -- file (清晰安全) |
| 存部分代码块 | git stash save -p |
git stash push -p |
| 包含未跟踪文件 | git stash save -u |
git stash push -u |
| 存已暂存内容 | git stash save --staged |
git stash push --staged |
四、结论与建议
-
新操作一律用
git stash push:特别是当你需要指定文件路径时,push的--分隔符能避免 99% 的意外错误。 -
旧脚本如果用了
save也不用急着改 :目前 Git 仍然兼容save,只是会在命令行里提示你这是废弃用法(deprecated)。但在编写新脚本或文档时,请务必使用push。 -
记忆口诀 :把
stash当成commit来记------commit用-m写消息,stash现在也用-m;commit后面加文件名要用--,stash push后面加文件名也要用--。
一句话总结 :git stash save 是"老黄历",git stash push 是"新标准"。为了不给自己挖坑,忘掉 save,只用 push。