How does git submodule add -b
work?
After adding a submodule with a specific branch, a new cloned repository (after git submodule update --init
) will be at a specific commit, not the branch itself (git status
on the submodule shows "Not currently on any branch").
I can't find any information on .gitmodules
or .git/config
about the submodule's branch or any specific commit, so how does Git figure it out?
Also, is it possible to specify a tag instead of a branch?
I'm using version 1.6.5.2.
If you add the submodule with -branch option you can use --remote option to update your submodule to the latest commit of that branch. If there is no branch given for a submodule, then git submodule update --recursive --remote will update the submodule the the remote branch that HEAD points to, which is usually master.
Adding a submodule to a Git repository and tracking a branch. If you add a submodule, you can specify which branch should be tracked via the -b parameter of the submodule add command. The git submodule init command creates the local configuration file for the submodules, if this configuration does not exist.
In order to checkout a Git tag, use the “git checkout” command and specify the tagname as well as the branch to be checked out. Note that you will have to make sure that you have the latest tag list from your remote repository.
Note: Git 1.8.2 added the possibility to track branches. See some of the answers below.
It's a little confusing to get used to this, but submodules are not on a branch. They are, like you say, just a pointer to a particular commit of the submodule's repository.
This means, when someone else checks out your repository, or pulls your code, and does git submodule update, the submodule is checked out to that particular commit.
This is great for a submodule that does not change often, because then everyone on the project can have the submodule at the same commit.
If you want to move the submodule to a particular tag:
cd submodule_directory git checkout v1.0 cd .. git add submodule_directory git commit -m "moved submodule to v1.0" git push
Then, another developer who wants to have submodule_directory changed to that tag, does this
git pull git submodule update --init
git pull
changes which commit their submodule directory points to. git submodule update
actually merges in the new code.
I'd like to add an answer here that is really just a conglomerate of other answers, but I think it may be more complete.
You know you have a Git submodule when you have these two things.
Your .gitmodules
has an entry like so:
[submodule "SubmoduleTestRepo"] path = SubmoduleTestRepo url = https://github.com/jzaccone/SubmoduleTestRepo.git
You have a submodule object (named SubmoduleTestRepo in this example) in your Git repository. GitHub shows these as "submodule" objects. Or do git submodule status
from a command line. Git submodule objects are special kinds of Git objects, and they hold the SHA information for a specific commit.
Whenever you do a git submodule update
, it will populate your submodule with content from the commit. It knows where to find the commit because of the information in the .gitmodules
.
Now, all the -b
does is add one line in your .gitmodules
file. So following the same example, it would look like this:
[submodule "SubmoduleTestRepo"] path = SubmoduleTestRepo url = https://github.com/jzaccone/SubmoduleTestRepo.git branch = master
Note: only branch name is supported in a
.gitmodules
file, but SHA and TAG are not supported! (instead of that, the branch's commit of each module can be tracked and updated using "git add .
", for example likegit add ./SubmoduleTestRepo
, and you do not need to change the.gitmodules
file each time)
The submodule object is still pointing at a specific commit. The only thing that the -b
option buys you is the ability to add a --remote
flag to your update as per Vogella's answer:
git submodule update --remote
Instead of populating the content of the submodule to the commit pointed to by the submodule, it replaces that commit with the latest commit on the master branch, THEN it populates the submodule with that commit. This can be done in two steps by djacobs7 answer. Since you have now updated the commit the submodule object is pointing to, you have to commit the changed submodule object into your Git repository.
git submodule add -b
is not some magically way to keep everything up to date with a branch. It is simply adds information about a branch in the .gitmodules
file and gives you the option to update the submodule object to the latest commit of a specified branch before populating it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With