views:

1257

answers:

3

How does git submodule add -b work?

After adding a submodule with a specific branch, a new cloned repo (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?

Thanks!

PS: I'm using 1.6.5.2.

+4  A: 

git submodules are a little bit strange - they're always in "detached head" mode - they don't update to the latest commit on a branch like you might expect.

This does make some sense when you think about it, though. Let's say I create repository foo with submodule bar. I push my changes and tell you to check out commit a7402be from repository foo.

Then imagine that someone commits a change to repo bar before you can make your clone.

When you check out commit a7402be from repo foo, you expect to get the same code I pushed. That's why submodules don't update until you tell them to explicitly and then make a new commit.

Personally I think submodules are the most confusing part of git. There are lots of places that can explain submodules better than I can. I recommend Pro Git by Scott Chacon.

Neall
I think it's time I start reading some git books, thanks for the recommendation.
Ivan
+12  A: 

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

'git pull' changes which commit their submodule directory points to. 'git submodule update' actually merges in the new code.

djacobs7
That's a very good explanation, thanks! And of course, after reading your answer, I realized the commit is saved inside the submodule itself (submodule/.git/HEAD).
Ivan
+1  A: 

A example of how I use git submodules.

  1. Creates a new repo
  2. Then clones another repo as submodule
  3. Then we have that submodule use a tag called V3.1.2
  4. And then we commit

And that looks a little bit like this:

git init 
vi README
git add README
git commit 
git submodule add git://github.com/XXXXX/xxx.yyyy.git stm32_std_lib
git status

git submodule init
git submodule update

cd stm32_std_lib/
git reset --hard V3.1.2 
cd ..
git commit -a

git submodule status

maybe it helps? (even thou I use a tag and not a branch)

Johan
It's basically the same answer as djacobs7, but thanks anyway :)
Ivan