`git stash push` 命令会把当前未提交的修改暂存起来。

12

假设当前提交为A,然后我创建一个新的提交B,在工作树目录中进行一些更改。现在我运行git stash pushgit stash push会存储什么?它只是存储我自从创建B以来在工作树目录中所做的更改,还是也包括我对B提交所做的更改,因为它是基于A提交的?

如果我然后检出提交A,并运行git stash pop,那么是否会应用我在创建提交B之后对工作目录所做的更改,或者也包括我对B提交自A以来所做的更改?

git stash push是否会将更改保存到最后提交的状态(即当前工作树目录与最后提交状态之间的差异),还是只保存当前状态?


2
问题是关于 git stashgit stash push 之间的区别(或缺乏差异)吗?因为尽管标题让我也想到了这个问题,但阅读问题正文后发现完全不同的一个话题。大家有没有什么遗漏的地方呢? - Romain Valeri
3个回答

13

根据文档:

将本地更改保存到新的stash条目中,并将它们回滚到HEAD(在工作树和索引中)。 此部分是可选的,可与存储的状态一起提供描述。

为了快速制作快照,可以省略 "push"。

换句话说,git stash pushgit stash相同。

此外,在文档中,已弃用git stash save,推荐使用git stash push


当你运行git stash时,尚未提交的任何更改都会被藏匿,将分支恢复到最新的提交。 如果您更改了分支并运行git stash pop,Git将把更改应用于新的分支。

但是,如果两个分支不同步,git stash pop可能会失败。 例如,文件 FOO 已推送到分支A,并且 git stash 存储了对该文件的更改。 分支B不包含 FOO ,因此 git stash pop 将无法将您的stash应用于分支B。


3
根据Git文档git stash pushgit stash相同:

调用不带参数的git stash等同于git stash push。默认情况下,存储为“WIP on branchname ……”,但您可以在创建时在命令行上提供更详细的消息。

因此,这将隐藏您从上次提交以来所做的所有新更改。 git stash pop执行相同操作git stash apply,只是它会将该隐藏状态从隐藏列表中删除,因此这是git stash push的反向操作。
总之,这意味着默认情况下,已经提交到您的分支的所有内容都不会被stash操作考虑,只有您自上次提交以来所做的新更改。

1
回答不同部分的问题:
git stash push stash 是什么?只包括我在工作树目录中自 B 创建以来所做的更改,还是包括我对提交 B 自 A 以来所做的更改?
是的,只有自 B 创建以来所做的更改被存储。
如果我然后检出提交 A,并运行 git stash pop,那么会将我在创建提交 B 后对工作目录所做的更改应用于其上,还是将我对提交 B 自 A 以来所做的更改也应用于其上?
您将在点 A 处将文件状态应用于自 B 创建以来所做的更改(提交是整个 repo 的快照)。
git stash push stash 是否将更改存储到最后提交的状态(即当前工作树目录与最后提交的状态之间的差异),还是仅存储当前状态? (我的回答的以下部分不准确。请参见 torek 的下面评论。) 只有从提交 B 到 git stash 时您的 repo 状态之间的更改将被存储,而不是整个 repo 的快照(如果您想要这样做,那就是一个适当的提交)。

1
实际上,git stash 会创建两个提交,这两个提交在几乎所有方面都是完全普通的提交。第一个提交是将当前的索引写出而产生的,因此在每个方面都是正常的提交。第二个提交是将工作树文件添加到临时索引中而产生的;它唯一与普通提交不同的地方在于它有当前提交和索引提交作为其(两个)父提交,欺骗 Git 的其他部分将其视为合并提交。然后 refs/stash 引用指向这第二个提交。(如果您使用 -a-u,则会得到第三个提交。) - torek
@torek 谢谢。 (1) "第二次提交是将工作树文件添加到临时索引中的结果",这个第二次提交是否包含所有工作树文件,还是只包含工作树和HEAD提交之间的差异?(2) 这是否解释了为什么“仅存储在提交B和git stash时刻的仓库状态之间的更改,而不是整个仓库的快照”,以及如何实现的? - Tim
@Tim:所有提交都包含整个文件。这是提交的本质:它保存了一些元数据,包括保留模式/文件名/哈希ID条目的“tree”对象。每个条目的哈希ID是从存储的文件数据计算出来的。(你可以想象一下,用差异列表制作一个文件,并将其保存为提交内部的文件,但这不是git stash所做的。)声称“只保存更改”是非常错误的:Git通过将它们与其他保存的文件进行比较,将保存的文件转换为更改,当需要时。 - torek
@torek 我知道提交本身的逻辑,但我发现我对暂存条目的理解相当偏差^^ 我被你纠正了! - Romain Valeri

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