Skip to content

Git submodules can now track branches

As of version 1.8.2, Git submodules can now track branches instead of specific commits.  This is good news as in many cases, this is exactly the behavior we want.  However, Git submodules are still not as flexible as Google repo, but since submodules are built into Git, the submodule command is a good solution in many cases.

The “git submodule update –remote” command is the key to tracking branches with submodules.   The following is from the Git man pages:

–remote
This option is only valid for the update command. Instead of using the superproject’s recorded SHA-1 to update the submodule, use the status of the submodule’s remote tracking branch. The remote used is branch’s remote (branch.<name>.remote), defaulting to origin. The remote branch used defaults to master, but the branch name may be overridden by setting the submodule.<name>.branch option in either .gitmodules or .git/config (with .git/config taking precedence).

This works for any of the supported update procedures (–checkout, –rebase, etc.). The only change is the source of the target SHA-1. For example, submodule update –remote –merge will merge upstream submodule changes into the submodules, while submodule update –merge will merge superproject gitlink changes into the submodules.

In order to ensure a current tracking branch state, update –remote fetches the submodule’s remote repository before calculating the SHA-1. If you don’t want to fetch, you should use submodule update –remote –no-fetch.

So, if you already have a Git submodule set up, its a simple matter to run git submodule update –remote to update the submodule to the latest master branch.  If you want a different branch, simple edit .gitconfig.

[submodule "meta-bec"]
   path = meta-bec
   url = git@github.com:cbrake/meta-bec.git
   branch = test

Now, if you run git submodule update –remote, Git will update the meta-bec submodule to the latest on the test branch.

This functionality is purely a convenience feature in the submodule update command.  In the actual repository, Git still stores submodules pointed to a particular commit.  The same thing could be accomplished with something like git foreach “git fetch && git checkout test”.  The branch option in .gitmodules functions more as documentation and convenience.  It is very handy to be able to look at .gitmodules and quickly determine that submodule X is tracking branch Y.  Normally, this would have to be documented elsewhere, or figured out in some other way.  Also, for build systems where you want the build to always track the production branches of various projects, update –remote gives you a convenient way to update the build tree.

Tags: