Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git submodule to track remote branch

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?

like image 638
Nambi Avatar asked Nov 14 '13 18:11

Nambi


People also ask

Can a submodule point to a branch?

You can set the submodule to track a particular branch (requires git 1.8. 2+), which is what we are doing with Komodo, or you can reference a particular repository commit (the later requires updating the main repository whenever you want to pull in new changes from the module – i.e. updating the commit hash reference).

Are git submodules a good idea?

Git submodules may look powerful or cool upfront, but for all the reasons above it is a bad idea to share code using submodules, especially when the code changes frequently. It will be much worse when you have more and more developers working on the same repos.

What does git submodule update -- Remote do?

If you track branches in your submodules, you can update them via the --remote parameter of the git submodule update command. This pulls in new commits into the main repository and its submodules. It also changes the working directories of the submodules to the commit of the tracked branch.

How do I change my submodule branch?

Go into the directory where the submodule resides and git checkout the correct branch/commit. Then go up one level and git add and git commit the directory. This will check in the submodule with the correct commit. And don't forget to run git submodule update --recursive on the other clients after updating them.

How to add a branch to a submodule in Git?

If you want to use a branch in the submodule (for example stable branches) you will have to add branch on .gitmodules file and use If you didn’t specify any branches and used --remote it will automatically fetch master branch. If you are developing the submodule as well you can use either --merge or --rebase as convenience

How do I track a remote branch in Git?

$ git checkout --track origin/dev Branch dev set up to track remote branch dev from origin. Switched to a new branch 'dev' This creates a new local branch with the same name as the remote one - and directly establishes a tracking connection between the two.

What is the difference between local and remote branches in Git?

By default, branches in Git have nothing to do with each other. However, when you tell a local branch to "track" a remote branch, you create a connection between these two branches.

How to update a submodule to the latest commit in Git?

But one can request to update that submodule to the latest commit of a branch of the submodule remote repo. Rather than going in each submodule, doing a git checkout abranch --track origin/abranch, git pull, you can simply do (from the parent repo) a: Since the SHA1 of the submodule would change, you would still need to follow that with:


Video Answer


3 Answers

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.

like image 194
VonC Avatar answered Oct 20 '22 13:10

VonC


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.

like image 45
darKoram Avatar answered Oct 20 '22 12:10

darKoram


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.

like image 1
BartBog Avatar answered Oct 20 '22 14:10

BartBog