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

Easiest way to get `svncopy --pin-externals`-like behaviour with Git submodules

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

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

TL;DR:这里无事可做。所有超级项目提交始终将所有内容定向到分离的 HEAD。 -bs 不在提交时使用,也不在 git adding 时使用,仅在 git submodule update --remoteing 时使用,即使那样你仍然在一个分离的 HEAD 上,只是一个不同的。


在 Git 中,子模块只是单独的 Git 存储库。超级项目提交 always 记录每个子模块将被强制使用的一个特定哈希。因此,如果您使用哈希 a123456 提交了一个超级项目,例如,超级项目的 a123456 already 引脚 each子模块:子模块 sub/A 永远固定(对于此提交)到 aaaaaaaa 并且子模块 moduleB 永远固定(对于此提交)到 bbbbbbb。当您返回到超级项目中提交 a123456 和 运行 git submodule update 时,sub/A 将分离到 sub/AaaaaaaaamoduleB 将分离到 bbbbbbb

要取消分离子模块,您必须 cd sub/A; git checkout mastercd moduleB; git checkout master。您可以使用 git submodule update --remote 半自动化此操作,它使用记录的分支,但实际所做的不是将 sub/A 切换到(它的)master 而是找出 [=15] =]'s remote's origin/master is, by hash ID, and switch sub/A to that commit as a detached HEAD.因此 sub/A 将继续处于分离 HEAD 模式。

在超级项目中使用git add只是从每个子模块中获取当前的HEAD(通常是分离的,但即使不是,也是git rev-parse报告的实际哈希ID)并记录它在超级项目的索引中,这样一个哈希 ID 将在下一个超级项目提交中。子模块中的分支名称在这里并不重要。 git submodule add 中那些 -b master 的唯一用途是用于 git submodule update --remote,即便如此,也并不是真正让子模块位于 分支 上,它只是自动更新子模块的分离头。