You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于git stash push指定文件却保存全部修改的异常问题咨询

为什么git stash push -- <file>会保存所有修改?

这个问题我之前也踩过坑,核心是对git stash push<pathspec>参数在已暂存修改场景下的行为理解偏差。

先拆解你的测试现象背后的逻辑

你执行git stash push -- README.md时,三个文件都处于暂存状态Changes to be committed),这时候Git的行为和你预期的不一样,原因如下:

  1. stash的本质:stash条目会完整记录当前的索引(暂存区)状态工作区状态——默认情况下,只要文件在索引里有修改,都会被纳入stash,不管你指定的pathspec。
  2. pathspec的实际作用:这里的-- README.md只是告诉Git:仅把匹配的文件回滚到HEAD状态,而不是“仅把匹配的文件存入stash”。所以执行命令后,README.md从暂存区被回滚,而LICENSE.mdsrc/attach.ts依然留在暂存区,但它们的修改已经被偷偷放进stash里了。
  3. 后续命令的表现
    • git status符合预期,因为只有README.md被回滚;
    • git stash show显示三个文件,因为stash里确实包含了所有暂存的修改;
    • git stash pop恢复所有stash里的内容,所以三个文件的修改都回来了。

手册描述的适用场景

手册里说“新的stash条目仅记录匹配pathspec的文件的修改状态”,这个描述是对的,但它只适用于未暂存的修改场景
如果三个文件都是未暂存的修改(Changes not staged for commit),执行git stash push -- README.md后:

  • stash只会包含README.md的修改;
  • LICENSE.mdsrc/attach.ts的修改会保留在工作区;
  • git stash show也只会显示README.md的变化。

如何实现“只将指定文件存入stash”?

如果你想仅保存README.md的修改,同时保留其他文件的修改,分两种情况:

情况1:README.md是未暂存状态

直接执行:

git stash push -- README.md

这时候stash只会包含README.md的修改,其他文件的修改留在工作区。

情况2:README.md已暂存

先把它从暂存区移出:

git restore --staged README.md

再执行git stash push -- README.md,就能只把README.md的未暂存修改存入stash。

如果你想专门保存README.md暂存状态,可以用--staged参数:

git stash push --staged -- README.md

这会仅将README.md的暂存修改存入stash,并回滚它的暂存状态,其他暂存文件不受影响。

内容的提问来源于stack exchange,提问作者ynn

火山引擎 最新活动