git stash save和git stash push有什么区别?

100

我什么时候应该使用git stash save而不是git stash push,反之亦然?


1
“git stash push”是一个命令吗?你可以使用“show”、“list”、“drop”、“pop/apply”,正如你所提到的,“save”。但是,要推送一个存储,我会创建一个分支并提交,然后将新分支“push”到远程。 - benhorgen
3
文档中似乎将git stash pushgit stash save视为类似的东西,但不完全相同。它没有解释它们之间的区别(至少我没看懂)。请参考https://git-scm.com/docs/git-stash。 - David Burson
8
git stash pushgit stash save的新同义词,但选项已经规范化。此外,您可以限制哪些路径被隐藏(并随后重置),而这在“保存”操作中是无法实现的。 - torek
3个回答

99

git stash save 命令接受一个非选项参数,即储藏信息。

git stash push 命令可以使用选项 -m 来指定储藏信息,同时也可以将一系列需要储藏的文件作为参数传入。


听起来是Git隐藏行为的一个不错补充。但是我在2.11.0版本中没看到支持该功能(Apple Git-81)。你知道这个功能是什么时候引入的吗? - benhorgen
3
看起来2.13.1版本是引入该功能的时候。https://git-scm.com/docs/git-stash/2.13.0 - benhorgen
8
可以这样说:save 命令是为了向后兼容而保留的,但最终将被 push 命令取代。 - void.pointer
9
是的,它终于在2.16中被宣布废弃 - phd
2
@void.pointer 是的。在 Git 项目中的提交 db37745 中:「虽然我们仍然保留 'git stash save',但更好的做法是将 'git stash' 的新用户指向更现代(和更具功能)的界面,而不是教他们那个我们可能想要逐步淘汰的旧版本。」 - M. Justin

58

为了明确起见,从Git 2.15/2.16(2018年第一季度)开始,git stash save已被弃用,取而代之的是git stash push(尽管git stash save目前仍可用)。

请参见commit c0c0c82commit fd2ebf1commit db37745(由Thomas Gummerer(tgummerer于2017年10月22日提交)。
(由Junio C Hamano -- gitster --commit 40f1293,2017年11月6日合并)

stash: 标记 "git stash save" 在手册页中已弃用

'git stash push' 修复了 'git stash save' 接口中的历史瑕疵。
由于 'git stash push' 具有更好、更一致的用户界面,同时拥有 'git stash save' 的所有功能,因此将 'git stash save' 标记为已弃用。

stash: 删除 "stash push" 中现在多余的帮助信息

使用 'git stash save' 接口时,用户很容易尝试添加以 "-" 开头的消息,这会被 'git stash save' 解释为命令行参数并失败。
针对这种情况,我们添加了一些额外的帮助信息,说明如何创建以 "-" 开头的消息的储藏。
对于 'stash push',消息通过 -m 标志传递,避免了这种潜在的问题。
现在只有以 "-" 开头的路径规范需要使用 "-- --<pathspec>" 来与命令行参数区分开来。
这在 git 命令行界面中相当常见,我们不会尝试猜测用户在其他情况下想要什么。
由于这种传递路径规范的方式在其他 git 命令中非常常见,并且我们没有提供任何额外的帮助信息,因此在 'git stash push' 的错误消息中也是如此。


自 Git 2.18(2018年第二季度)开始,命令行补全(在contrib/中)已经了解到"git stash save"已被弃用("git stash push"是新世界中的首选拼写),并且不会将其作为可能的补全候选项提供,当"git stash push"可以使用时。

请参见 commit df70b19commit 0eb5a4f(由Thomas Gummerer(tgummerer)于2018年4月19日提交)。
(由Junio C Hamano -- gitster --合并于commit 79d92b1,2018年5月8日)

completion: 使stash -p成为stash push -p的别名

我们在manpage中将'git stash -p'定义为'git stash push -p'的别名。在完成脚本中也要这样做,这样当用户使用'git stash -p --<tab>'时,所有可以给'git stash push'的选项都会被自动补全。
目前,用户将获得的唯一附加选项是'--message',但未来可能会有更多。


命令行自动完成脚本(在contrib/中)试图将"git stash -p"作为"git stash push -p"进行自动完成,但这太过于激进,还影响了"git stash show -p",已经在Git 2.28(2020年第三季度)中得到了修正。

请参见commit fffd0cf(2020年5月21日),作者为Ville Skyttä(scop
(由Junio C Hamano -- gitster --commit a8ecd01合并,2020年6月9日)

completion: 不要用-p覆盖给定的stash子命令

签名:Ville Skyttä

df70b190(“completion: make stash -p and alias for stash push -p”,2018-04-20,Git v2.18.0-rc0 -- merge listed in batch #5)希望确保"git stash -p <TAB>"提供与"git stash push -p <TAB>"相同的补全,但是它通过在命令行上找到-p选项时强制将$subcommand设置为"push"来实现。

这会损害任何可以使用"-p"选项的子命令,即使已经明确给出了子命令,例如"git stash show -p",更改添加的代码也会覆盖用户给出的$subcommand

修复方法是确保只有在尚未给出$subcommand时才默认为"push"。


3
“push”命令旨在始终使用,而不是使用“save”命令,因为它更灵活,使用更传统的命令行参数。出于这些原因,“save”命令已被弃用。
替代方案:
“push”选项在2.13.0中引入,以比“save”更传统地提供命令行参数。
这种变化的理由已在添加Git命令时的提交消息中记录: f5727e2
引入一个新的git stash push动词,除了git stash save之外。推动动词用于从当前命令行参数过渡到更传统的方式,其中消息作为-m选项的参数给出。
这使我们可以像其他Git命令一样在命令行参数的末尾有pathspecs,以便用户可以说哪个子集的路径要隐藏(并留下其他路径)。

c0c0c82:

通过“git stash save”接口,用户可以轻松地尝试添加以“-”开头的消息,而“git stash save”会将其解释为命令行参数并失败。 […]

对于“stash push”,消息使用“-m”标志传递,避免了这种潜在问题。现在只有以“-”开头的路径规范需要使用“--<pathspec>”进行与命令行参数的区分。这在git命令行界面中非常常见,我们不会在其他情况下猜测用户的意图。

fd2ebf1:

“git stash push”具有“git stash save”的所有功能,并具有更好、更一致的用户界面。

弃用

“save”命令在Git的2.16.0版本中已经被正式弃用:
“git stash save”已被“git stash push”所取代。
“save”命令的弃用已在其文档中解释:
“save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [] 此选项已被 git stash push所取代。它与“stash push”的区别在于它不能采用pathspec。相反,所有非选项参数都被连接起来形成贮藏信息。
短形式:
除了标准形式的命令外,push 还有一种简短的形式,其中 "push" 被省略在 stash 命令中。而 save 命令则没有这样的等效形式。根据文档

为了快速创建快照,您可以省略 "push"。在此模式下,不允许使用非选项参数,以防止拼写错误的子命令导致不必要的存储条目。两个例外是 stash -p,它的作用相当于 stash push -p 和路径规范元素,它们允许在双破折号 -- 后使用以消除歧义。

git stash
git stash -p

命令比较

通过阅读文档,我认为这应该是两个命令的相当完整的比较:

push save
git stash push git stash save
git stash push -m <message> git stash save <message>git stash save -m <message>
git stash push -m <message>(消息以“-”开头) git stash save -m <message>
git stash push [--] <pathspec>…​ N/A(不可能)
git stash push --pathspec-from-file=<file> N/A(不可能)
git stash git stash save
git stash -p git stash save -p
git stash -- <pathspec>…​ N/A(不可能)
如此比较显示,savepush 之间的显著变化包括:
  • 使用路径规范(pathspecs)可以使用 push 创建部分存储区(partial stash),但不能使用 save。路径规范可以作为内联参数提供,也可以使用 -- 提供。
  • 消息可以作为内联参数使用 save,但必须通过 -mpush 中提供。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接