git stash create和git stash store的目的是什么?

25
git-scm的文档中可以看到,有两个与脚本相关但并不常见的命令:git stash creategit stash store

create

创建一个stash(它是一个普通的提交对象),并返回其对象名称,而不将其存储在ref命名空间中。 这旨在用于脚本。 这可能不是您想要使用的命令; 请参见上面的“save”。

store

在stash ref中存储通过git stash create创建的给定stash(这是一个悬空的合并提交),并更新stash reflog。 这旨在用于脚本。 这可能不是您想要使用的命令; 请参见上面的“save”。

假设我们考虑自动化脚本的情况下,与通常的git stash save 和类似功能相比,git stash create git stash store 有哪些优势?

有趣的事实:当没有本地更改需要存储时,git stash create不会输出任何内容,而git stash save则会输出信息。 - BlackVegetable
希望有人能回答这个问题,因为我也完全被困扰了。 - jeffdill2
3个回答

17

很不幸,Andrew 上面展示的好例子并非全都适用,原因是:

  • 如果有本地更改,则 git stash create 将创建一个无引用提交,但不会实际清除本地更改。

  • 如果没有本地更改,则根本不会创建提交(正如 BlackVegetable 指出的那样)。在这种情况下,我们不应该在最后执行 apply

  • (还有一点小问题:Andrew 忘记保留并使用 create 生成的提交 ID)。

有了这个认识,我觉得应该像这样使用:

# Save the local changes, keep a reference to them, and clear them
stashed_commit="$(git stash create)"
git reset --hard

# Do your thing
git fetch
git rebase

# If there were local changes, then restore them
if [ -n "${stashed_commit}" ]
then git stash apply "${stashed_commit}"
fi

说起来笨重不堪!

唉。如果我能在顶部只输入git stash save --allow-empty,在底部只输入git stash pop,那就简单多了。

我希望我是错的,请纠正我!


3
请注意,在rebase的特定情况下,我们实际上可以使用git rebase --autostash来自动执行上述操作。 - joeytwiddle
@torek git stash create 不会删除它存储的内容。git stash save 会删除,但很难确定它是否实际存储了任何内容(没有错误代码,搜索消息可能不稳定)。此外,使用 create 我们根本不会触及存储堆栈,这有利有弊。 - joeytwiddle
啊,嗯,这很有趣。git stash store 命令会重置吗?好的,那是一个 shell 脚本,我去查一下...答案:不会,只有 git stash savegit stash push 命令会执行重置操作,并使用 git reset --hard -q 命令,除非指定了路径。无论如何,我会删除上面错误的评论。 - torek

9

当编写需要隐藏实现细节的脚本并且不希望干扰用户存储的stash reflog时,您可以使用git stash create

根据接下来发生的情况,例如错误,您可能会决定毕竟还是要干扰stash reflog,这时您可以使用git stash store

显然,常规stash可以通过使用create然后store来实现,但我也可以想象它被用于假设的update-branch命令,执行以下操作:

git stash create
git fetch
git rebase
git stash apply

1
有趣的是,它似乎在第一阶段没有干扰stash reflog的优势。确实很奇怪。 - BlackVegetable

0
Git 2.43 (Q4 2023)澄清了git stash storegit stash create之间的关系:
使用随机提交给“git stash store(man),该提交不是由git stash create(man)创建的,现在会报错。
查看提交 d9b6634(2023年10月11日)由Junio C Hamano(gitster完成。
(由Junio C Hamano -- gitster --提交 626f689中合并,2023年10月23日)

stash:小心我们存储的内容

"git stash store"(man) 的目的是存储 git stash create(man) 生成的内容,因为这两个命令是面向最终用户的 "git stash save"(man) 命令的实现细节。
尽管已经明确记录了这一点,但用户仍然会尝试一些愚蠢的操作,比如使用 "git stash store" HEAD 来使他们的存储变得无法使用。

更糟糕的是,因为 "git stash drop"(man) 不允许删除这样的存储条目,所以 "git stash clear"(man) 是唯一的恢复方式。
重用阻止 "drop" 对这样的存储条目起作用的逻辑,教会 "store" 避免在第一次存储时存储非存储条目对象。
错误信息:
store called with non-stash commit

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