使用Git子模块获得类似svncopy --pin-externals`行为的最简单方法

时间:2019-04-24 15:03:40

标签: git git-submodules

当前,我的项目以detached HEAD的方式使用Git子模块。在常规开发工作流的上下文中,将子模块指向相应的远程分支机构的提示(git submodule add -b master ...)会更加方便,因此将自动考虑子模块中的最新更改。但是,在创建必须随时间保持不变的标记时,子模块链接必须固定在创建标记时使用的那些特定提交上。

在SVN中,只需在标签创建命令中添加--pin-externals参数即可实现此固定,但是Git似乎没有与其直接等效的功能。我最好的选择是什么?

1 个答案:

答案 0 :(得分:1)

TL; DR:这里无事可做。所有超级项目提交始终将所有内容定向到分离的HEAD。提交时-bgit add都不会使用git submodule update --remote,只有a123456才使用a123456,即使那样,您仍然处于独立的HEAD上,只是一个不同的HEAD。


在Git中,子模块只是单独的Git存储库。超级项目提交始终记录每个子模块将被强制使用的一个特定哈希。因此,例如,如果您使用哈希sub/A提交了一个超级项目,则该超级项目的aaaaaaaa 已经固定了每个子模块:子模块{{1 }}被永久地固定(用于此提交),例如moduleB,子模块bbbbbbb被永久地固定(用于此提交)a123456。当您返回在超级项目中提交git submodule update并运行sub/A时,sub/A将分离到aaaaaaaa的{​​{1}}上,而moduleB被分离到bbbbbbb

要取消分离子模块,必须cd sub/A; git checkout mastercd moduleB; git checkout master。您可以使用git submodule update --remote半自动执行此操作,该操作使用记录的分支,但是实际上不执行的操作不是将sub/A切换到master,而是找出{{1 }}的远程sub/A通过哈希ID将origin/master切换为该提交作为独立的HEAD。因此sub/A将继续处于分离的HEAD模式。

在超级项目中使用sub/A只是从每个子模块中获取当前的git add(通常是分离的,但即使不是HEAD报告的实际哈希ID)也记录在其中超级项目的索引,以便一个哈希ID将在下一个超级项目提交中。子模块中的分支名称在这里并不是很重要。 git rev-parse中这些-b master的唯一用途是用于git submodule add,即使这样,也并不是使子模块位于 branch 上,只是为了自动更新子模块的分离式HEAD。