问题描述
git stash -k -u
在更新到最新版本之前。
通常,它输出:No local changes to save
但是一段时间以来,它一直在输出:Saved working directory and index state WIP on generated: build
,即使未对工作副本进行任何更改。
当我尝试检查任何隐藏物的内容时,它也显得完全空白:
$ git stash list
stash@{0}: WIP on generated: bc0c9f6 build
stash@{1}: WIP on generated: 1d83819 build
stash@{2}: WIP on generated: 6aff261 build
stash@{3}: WIP on generated: ac3f8a9 build
stash@{4}: WIP on generated: bf0d020 build
stash@{5}: WIP on generated: ba972db build
stash@{6}: WIP on generated: 2c5cfe3 build
$ git stash show stash@{0}
$ git stash show stash@{1}
等等...所有存储的输出为空。如果我为-p
命令指定stash show
标志,则相同。
我需要帮助弄清楚这些存储的内容,以便推测为什么首先要创建它们。
解决方法
存储实际上是一个提交,或更准确地说,是两个或三个提交(取决于存储选项)。由于您使用的是-u
,因此可以得到三个提交的变体。
我将这三个提交称为i
,w
和u
(如果存在)。 i
的提交是通过提交索引内容来进行的,与git commit
相同,只是该提交不会进入任何分支。
u
提交(如果存在)仅包含未跟踪但未被忽略的文件(使用-u
;使用-a
包含更多文件)。进行此u
提交后,Git然后从您的工作树中删除此提交中存储的所有文件。
w
提交始终位于最后,并且包含与i
提交中相同的文件集(文件名),但是 w
提交中这些文件的内容与这些文件的工作树副本中的内容匹配,而不是索引副本中的内容。
当git stash
不 -u
在HEAD
提交,当前索引和具有以下名称的工作树文件之间没有发现差异时索引中的副本,git stash
拒绝进行新的存储,而是产生您提到的错误消息(No local changes to save
)。但是,如果您确实有未跟踪的文件,则应进行存储,然后删除那些未跟踪的文件。这将导致i
和w
内容匹配且都匹配运行HEAD
时提交的git stash
的存储。
git stash
命令是在最近的Git中重写的,其某些极端情况的行为可能已更改。如果是这样,那就是一个错误,您应该向Git社区报告(理想情况下,是使用行为不同的复制器和特定Git版本)。
请注意,git stash show
只是查看w
提交。像所有提交一样,i
,u
和w
提交中的所有三个都可以具有父提交。 i
提交的(单)父级是您进行存储时的当前提交。 u
提交(如果存在)是根提交(没有父提交)。 w
提交有两个或三个父级:第一个是您进行存储时当前的提交,第二个是i
提交,第三个(如果存在)是u
提交。也就是说,我们可以这样绘制提交图:
...--F--G--H <-- current-branch (HEAD)
|\
i-w <-- stash
/
u
名称stash
(全名refs/stash
)指向w
提交。当前分支,这里current-branch
(全名refs/heads/current-branch
)指向当前提交,特殊名称HEAD
附加到名称current-branch
上,以便Git可以找到提交H
的哈希ID。
因此,提交H
是i
的父级,也是w
的第一个父级。 Git通过u
是否有第三父级来检测提交w
是否存在。
git stash show -p
等效于git diff stash stash~1
,即将提交H
中的文件内容与提交w
中的文件内容进行比较。如果进行隐藏的原因是u
存在,或者i
与i~1
不同,则无需w
与w~1
不同。