Git submodule to track remote branch
Asked Answered
A

3

22

I'm trying to use git submodules for aggregating 10+ repositories into one structure for easy development.

It is supposed to clone the module and checkout a branch. Instead, the module is checked out in detached head mode.

git clone [email protected]:org/global-repository.git
git submodule update —init
cd config-framework
git status

$git status
#HEAD detached at b932ab5
nothing to commit, working directory clean

gitmodules files seems to be okay

$cat .gitmodules 
[submodule "config-framework"]
        path = config-framework
        url = [email protected]:org/config-framework.git
        branch = MY_BRANCH

We want the MY_BRANCH branch to be checked out by default, rather than detached head. How do we achieve that?

Antiphrasis answered 14/11, 2013 at 18:59 Comment(2)
This is the way submodules work. The master project references a specific commit, not a branch.Turf
Does this answer your question? How can I specify a branch/tag when adding a Git submodule?Bootlace
R
25

Submodules are always checked out in a detached HEAD mode.

That is because a submodule will checkout the SHA1 stored in the special entry in the index of the parent repo.

Plus, if you want a submodule to follow the branch you have registered in the .gitmodules, you need:

git submodule update --init --remote

The --remote will make a git fetch, plus a checkout of the new HEAD.
Alas, even that checkout will be of a commit, not of the branch (since you have no local branch by default in a submodule), so... back to a detached HEAD mode.
See more at "Git submodules: Specify a branch/tag".

You can try (not tested) a:

git submodule foreach 'git checkout -b $(git config -f /path/to/parent/repo/.gitmodules --get submodule.$path.branch)'

I take advantage of the fact git submodule foreach has access to '$path', the name of the submodule directory relative to the superproject.


There was an attempt to specify a branch for a submodule to be automatically checked out in (commit 23d25e4 for Git 2.0).... but it got reversed (commit d851ffb, April 2d 2014)!
It might come soon, but not in its current implementation.

Ramonramona answered 16/11, 2013 at 9:26 Comment(1)
Would appreciate, if you could answer my related question here: https://mcmap.net/q/22546/-proper-version-control-workflow-for-a-mixture-of-repositories/2872891. Thank you!Orelia
P
1

If your plan is to contribute to a submodule, the best approach is to check it out separately as a regular git repo. Do you work in branches with different remotes. Then point your submodule at the single remote you want to use for testing.

Pneumodynamics answered 3/10, 2015 at 23:14 Comment(0)
N
1

In order to get this done, I always use the following command (slightly based on VonCs proposal earlier:

export top=$(pwd)
git submodule foreach --recursive 'b=$(git config -f ${top}/.gitmodules submodule.${path}.branch); case "${b}" in "") git checkout ${sha1};; *) git checkout ${b}; git pull origin ${b};; esac'

It checks out all submodules (recursively) at their "right" branch (if set) and otherwise at the head as last committed.

Nierman answered 17/8, 2018 at 10:43 Comment(5)
Interesting approach, but I think a simple git submodule update --remote --recursive is enough these days (Git 2.18+)Ramonramona
The problem with that approach is (though I did not test it on 2.18+ yet) that it will update ALL submodules, also those that do not have a remote tracking branch, if I understand correctly. Now, my submodule structure basically consists of an archive (in which all submodules are frozen to a given sha) and then some submodules that need tracking. The current submodule system does not seem to be able to distinguish between those. Also, my approach allows for selective fetching... (I know, I have quite specific needs ;-) )Nierman
I agree. +1. I though I sax a similar approach before... in one of my old answers: https://mcmap.net/q/13074/-how-can-i-specify-a-branch-tag-when-adding-a-git-submodule. Note that you can exclude submodules from update: https://mcmap.net/q/13593/-how-to-only-update-specific-git-submodulesRamonramona
"also those that do not have a remote tracking branch, if I understand correctly":... sadly, yes. I illustrated that in https://mcmap.net/q/13322/-git-track-branch-in-submodule-but-commit-in-other-submodule-possibly-nested two years ago.Ramonramona
Ah, I thought there was another question in which we discussed this. Excellent explanation as always :-)Nierman

© 2022 - 2024 — McMap. All rights reserved.