A <-B <-C <--master
名称master
指向最后一次提交,C
。提交C
本身指向较早的提交B
,它又指向第一次提交A
。(因为A
是第一次提交,所以它不会指向任何地方,这就是Git停止遍历的方式。)
要添加一个新的提交 - 让我们称其为D
- Git将新提交写出,以便它指向现有提交C
,而C
曾经是分支上的最后一次提交。然后Git将D
的实际哈希ID(无论是什么)写入名称master
中:
A <-B <-C <-D <--master
如果将标签名称指向其中一个提交,则该标签名称保持不变。A <-B <-C <-D <--master
^
|
tag:v11
当我们添加一些新的提交时,我们得到:A <-B <-C <-D <-E <-F <--master
^
|
tag:v11
标签名称没有变动过,并且永远不应该改变。(您可以手动“移动”一个标签,方法是删除它并创建具有相同名称的另一个标签,或使用其中一种强制选项,但一般情况下不应这样做。)
如果发布分支被删除,是否仍然可以检出此标记的提交记录...
当然可以。分支名称、标签名称和其他名称用于定位一个特定的提交记录。您可以使用该名称直接转到该提交记录。只要名称本身继续存在,该提交本身将在Git存储库中保留。
找到某个提交记录(通常通过名称),Git可以使用嵌入在每个提交记录中的内部箭头向后移动历史记录。这意味着如果有一个提交记录 D
的名称,就像上面的示例图中一样,Git 可以使用 D
找到 C
,从而找到 B
,再找到 A
。因此,这四个提交将始终保留在此存储库中,因为可以找到 D
。
请注意,名称 master
定位到提交记录 F
,这意味着提交记录 F
被保留。提交记录 F
定位到提交记录 E
,后者又定位到 D
,以此类推;因此,这些提交也将被保留。因此,有两个名称意味着必须保留 D
及更早的提交记录。如果删除其中任何一个名称,则 D
保留名称的数量将减少为1,但是仍然必须保留 D
。不过,如果我们删除的名称是 master
,那么提交记录 F
就不再需要保留了。如果丢弃提交记录 F
,那么表示提交记录 E
也无法找到,因此提交记录 E
也可以被删除。
如果我们添加另一个名称以查找提交记录 F
,则在某种意义上,删除名称 master
就变得安全了。删除名称 master
将实际上“遗忘”了 master
中的最后一个提交,在此时,它是提交记录 F
,但是提交记录 F
将通过其他某些名称找到,因此不会被删除。
请注意,任何合并提交都有两个(或多个1)箭头从中出来。如果可以找到该合并提交,则从它出来的箭头会保留沿着每个路径向下的所有较早的提交记录。因此,一旦您将某些分支端提交(由某些分支名称标识)合并到要保留其名称的其他分支中,即可安全删除已合并分支的名称:您将无法直接找到该末端提交记录,但是可以通过找到具有其作为其中一个额外父提交记录哈希 ID 的 合并提交 找到它。
1Git 将这种具有多于两个“腿”出来的合并称为章鱼合并(octopus merge)。这可能就是为什么 GitHub 使用
Merge Tag '1.x.y'
的提交记录,我不明白为什么除了 Merge branch 'hotfix/1.x.y' into master
之外还需要它。有人知道为什么会创建这些看似多余的提交记录吗? - avatarofhope2答案是正确的,但有点复杂。以下是简短的回答:
如果发布分支包含标签,并且在 release/1.x.y 的最后一个发布版本之后将发布分支合并到主干中,那么标签也会被合并吗?
标签与分支关系不大,它们只指向特定的提交 - 不管提交在哪个分支中。
所以,是的,在合并后标签仍然可用。
对于长期支持,我的问题是:
假设十年后有人想检出标记1.1.1的状态。如果删除了发布分支但已将其合并到主分支中,我们有主分支,能否检出此标记的提交?
可以。