Currently my project uses Git submodules in a detached HEAD
way. In context of a regular development workflow, it would much more convenient to point submodules to the corresponding remote branches' tips (git submodule add -b master ...
) so the freshest changes in submodules are taken into account automatically. But when it comes to creating tags, which must remain constant over time, submodule links must be fixed on those specific commits that are used when a tag is being created.
In SVN, this fixation can be achieved just by adding the --pin-externals
argument to a tag creation command, but it looks like Git has no direct equivalent for it. What is my best bet here?
TL;DR: there's nothing to do here. All superproject commits always direct everything to detached HEADs. The -b
s are not used when committing, nor when git add
ing, only when git submodule update --remote
ing, and even then you're still on a detached HEAD, just a different one.
In Git, submodules are just separate Git repositories. A superproject commit always records the one specific hash to which each submodule will be forced. So if you've made a superproject commit with hash a123456
, for instance, the superproject's a123456
already pins each submodule: submodule sub/A
is fixed forever (for this commit) onto, say, aaaaaaaa
and submodule moduleB
is fixed forever (for this commit) onto bbbbbbb
. When you go back to commit a123456
in the superproject and run git submodule update
, sub/A
will be detached to sub/A
's aaaaaaaa
and moduleB
will be detached to bbbbbbb
.
To un-detach the submodules, you must cd sub/A; git checkout master
and cd moduleB; git checkout master
. You can semi-automate this using git submodule update --remote
, which uses the recorded branch, but what that actually does is not switch sub/A
to (its) master
but rather to find out what sub/A
's remote's origin/master
is, by hash ID, and switch sub/A
to that commit as a detached HEAD. So sub/A
will continue to be in detached HEAD mode.
Using git add
in the superproject just takes the current HEAD
(usually detached, but even if not, the actual hash ID as reported by git rev-parse
) from each submodule and records it in the superproject's index, so that the one hash ID will be in the next superproject commit. The branch name in the submodule is not really important here. The only use of those -b master
s in git submodule add
is for git submodule update --remote
, and even then it's not really to make the submodule be on a branch, it's just to automatically update the submodule's detached-HEAD.