(1)不。通过git stash
保存的更改将作为一对(或有时是三个)提交进行保存。这些提交由名称stash
引用。如果您将分支名称和标签视为提交的标签(这就是它们所代表的),那么您可以画出一个图像,例如:
(1) No. 通过git stash
保存的更改将被保存成一对(或有时是三个)提交。这些提交会被命名为stash
。如果您把分支名称和标签看作是提交记录的标签(实际上就是这样),那么您可以画出下面这张图片:
O1 - O2 <-- other_branch
/
M1 - M2 - M3 - M4 <-- master
\
B1 - B2 - B3 <-- branch
.
.......................<-- tag
(如果我可以以不同的颜色标记标签,可能会更有效果;我使用点号来表示标签tag
指向提交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
指向提交B3
。)
这里i
和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
没有直接的标签,但隐藏点指向w
,而w
又回指到B3
。所以所有东西仍然存在,并且只要存储(或者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
和git commit
来提交所有的更改,你将会得到一个(单一,非合并)提交,我们可以称之为B4
,在分支branch
上。 分支标签将被移动到指向B4
,然后你将检出other_branch
并删除该标签,这样就会得到:
O1 - O2 <-- HEAD=other_branch
/
M1 - M2 - M3 - M4 <-- master
\
B1 - B2 - B3 - B4
这几乎(但并非完全)相同。
请注意,如果标签tag
仍然指向B1
,提交B1
将一直保留,直到该标签也被删除。提交B2
至B4
或B2
至w
只会在引用日志中保持不可见的状态下存在。在30天后(或您设置为引用日志过期的时间),引用日志条目将过期,这些提交将有资格进行垃圾回收。