让我们说:
top.git
└── sub.git => 75fc7
top.git
引用75fc7
中的提交sub.git
。sub.git
既没有分支也没有标记导致提交75fc7
(无法访问)。 sub.git
最终会垃圾收集此提交75fc7
,因为没有任何内容可以覆盖吗?
AFAIK,Git子模块的设计方式是,在这个例子中,sub.git
无法确定它是任何其他存储库的子模块这一事实。换句话说,提交75fc7
实际上是垃圾收集的候选者。如果它们可能“忘记”所需的提交,那么恢复所有子模块的状态将是不可靠的。
答案 0 :(得分:3)
是的,提交最终将被垃圾收集。
但不要忘记,要重用,其父级仓库引用的子模块还必须发布记录的SHA1(记录为 gitlink ,special entry in the index of the parent repo )。
如果没有发布SHA1(推送到上游仓库),那么父仓库的任何克隆都无法检查子模块。
这意味着子模块必须推送记录的SHA1,这使得SHA1被引用(通过分支或标签,在上游仓库上推送)
所以问题不在于垃圾收集器,而是父垃圾收集器将其子模块签出到正确的SHA1的能力。
我的场景(未明确提及)实际上是不同的,更具体。如果提交实际上被推送到
top.git
和sub.git
的上游怎么办?
然后您无需等待gc
删除不可访问的SHA1以解决问题。
如果发布的SHA1不再可用,则意味着top.git
的任何克隆都无法检出右侧SHA1的sub.git
子模块库(即使gc尚未运行),因为无论如何,未引用的SHA1不会成为sub.git
克隆的一部分。
要理解的关键点:上游回购sub.git
不知道它被另一个上游回购用作子模块(如top.git)。
如果sub.git
由于任何原因(top.git
或其他gc
或...)而未包含正确的SHA1(由rebase/push --force
使用),则克隆为{ {1}}将无法将子模块恢复到正常状态。
答案 1 :(得分:2)
实际上,很容易测试 thanks to this answer 。
是的,提交是垃圾收集的,即使它被顶级存储库引用。
然后,它要求在顶级存储库中可以使用哪些提交中的一些度量或规则,以便在将来的任何时间可靠地恢复整个树跨越子模块。 此类提交必须是任何长期维护的分支或标记的祖先。