(1) 否。保存的更改git stash
被保存为一对(或有时三个)提交。这些提交由名称引用stash
。如果您将分支名称和标签视为提交的标签(它们就是这样),那么您可以绘制图片,例如:
O1 - O2 <-- other_branch
/
M1 - M2 - M3 - M4 <-- master
\
B1 - B2 - B3 <-- branch
.
.......................<-- tag
(如果我可以对标签进行不同的着色,这可能会更好;我用点表示标签tag
指向 commit B1
,即“在分支上branch
”)。
如果您在分支上branch
并且有一些未保存的更改并运行git stash
,这就是它的作用:
/
M1 - M2 - M3 - M4 <-- master
\
B1 - B2 - B3 <-- HEAD=branch
| \
i - w ........<-- stash
(我离开了图表other_branch
,tag
但他们仍然在那里。我写信HEAD=branch
暗示那HEAD
指向branch
,并且branch
指向 commit B3
。)
这里是您编辑的“索引”和“工作树”i
状态。该名称直接指向 commit ,并且有两个父级(即,即使它根本不是真正的合并,也是一个“合并提交”),作为它的第一个父级和第二个父级。w
stash
stash
w
w
B3
i
当您运行时git branch -D
,您所做的就是擦除标签。所以假设你git checkout other_branch
,然后擦除标签branch
。现在你有了这个:
O1 - O2 <-- HEAD=other_branch
/
M1 - M2 - M3 - M4 <-- master
\
B1 - B2 - B3
| \
i - w ........<-- stash
没有直接的标签,B3
但 stash 指向w
,又w
指向B3
。所以一切都还在那里,只要 stash(或 reflog,或两者兼而有之)保持B3
在 git 的内部雷达上,它就会一直存在。
(2) 否:如您所见,stash 仍然有对分支的引用。然而,一旦你放下那个存储——例如,擦除stash
标签git stash drop
——你会得到这个:
O1 - O2 <-- HEAD=other_branch
/
M1 - M2 - M3 - M4 <-- master
\
B1 - B2 - B3
| \
i - w
如果您git add
-ed 和git commit
ed 所有更改,您将获得(单个,非合并)提交,我们可以将其称为B4
, on branch
。分支标签将被移动到指向B4
,然后您将签出other_branch
并删除标签,给出:
O1 - O2 <-- HEAD=other_branch
/
M1 - M2 - M3 - M4 <-- master
\
B1 - B2 - B3 - B4
这几乎(但不完全)相同。
(请注意,如果 tagtag
仍然指向B1
,则 commitB1
将一直存在,直到标签也被删除。通过 或 through 提交B2
,B4
只要B2
它们w
保持在那里,但在 reflog 中不可见,就会一直存在。30 天后(或其他任何时间)您为 reflog expiry 设置),reflog 条目过期,并且这些提交变得有资格进行垃圾收集。)