Adding a branch
option in .gitmodule
is NOT related to the detached behavior of submodules at all. The old answer from @mkungla is incorrect, or obsolete.
From git submodule --help
, HEAD detached is the default behavior of git submodule update --remote
.
First, there's no need to specify a branch to be tracked. origin/master
is the default branch to be tracked.
--remote
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 toorigin
. The remote branch used defaults tomaster
.
So why is HEAD detached after update
? This is caused by the default module update behavior: checkout
.
--checkout
Checkout the commit recorded in the superproject on a detached HEAD in the submodule. This is the default behavior, the main use of this option is to override
submodule.$name.update
when set to a value other thancheckout
.
To explain this weird update behavior, we need to understand how do submodules work?
Quote from Starting with Submodules in book Pro Git
Although sbmodule
DbConnector
is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git sees it as a particular commit from that repository.
The main repo tracks the submodule with its state at a specific point, the commit id. So when you update modules, you're updating the commit id to a new one.
If you want the submodule merged with remote branch automatically, use --merge
or --rebase
.
--merge
This option is only valid for the update command. Merge the commit recorded in the superproject into the current branch of the submodule. If this option is given, the submodule's HEAD will not be detached.
--rebase
Rebase the current branch onto the commit recorded in the superproject. If this option is given, the submodule's HEAD will not be detached.
All you need to do is,
git submodule update --remote --merge
# or
git submodule update --remote --rebase
Recommended alias:
git config alias.supdate 'submodule update --remote --merge'
# do submodule update with
git supdate
There's also an option to make --merge
or --rebase
as the default behavior of git submodule update
, by setting submodule.$name.update
to merge
or rebase
.
Here's an example about how to config the default update behavior of submodule update in .gitmodule
.
[submodule "bash/plugins/dircolors-solarized"]
path = bash/plugins/dircolors-solarized
url = https://github.com/seebi/dircolors-solarized.git
update = merge # <-- this is what you need to add
Or configure it in command line,
# replace $name with a real submodule name
git config -f .gitmodules submodule.$name.update merge
git submodule --help