How can I specify a branch/tag when adding a Git s

2018-12-31 01:30发布

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.

11条回答
与风俱净
2楼-- · 2018-12-31 02:18

Git 1.8.2 added the possibility to track branches.

# add submodule to track master branch
git submodule add -b master [URL to Git repo];

# update your submodule
git submodule update --remote 

See also Git submodules

查看更多
查无此人
3楼-- · 2018-12-31 02:18

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 repository bar before you can make your clone.

When you check out commit a7402be from repository 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.

查看更多
看淡一切
4楼-- · 2018-12-31 02:21

To switch branch for a submodule (assuming you already have the submodule as part of the repository):

  • cd to root of your repository containing the submodules
  • Open .gitmodules for editing
  • Add line below path = ... and url = ... that says branch = your-branch, for each submodule; save file .gitmodules.
  • then without changing directory do $ git submodule update --remote

...this should pull in the latest commits on the specified branch, for each submodule thus modified.

查看更多
只若初见
5楼-- · 2018-12-31 02:21

I have this in my .gitconfig file. It is still a draft, but proved useful as of now. It helps me to always reattach the submodules to their branch.

[alias]

######################
#
#Submodules aliases
#
######################


#git sm-trackbranch : places all submodules on their respective branch specified in .gitmodules
#This works if submodules are configured to track a branch, i.e if .gitmodules looks like :
#[submodule "my-submodule"]
#   path = my-submodule
#   url = git@wherever.you.like/my-submodule.git
#   branch = my-branch
sm-trackbranch = "! git submodule foreach -q --recursive 'branch=\"$(git config -f $toplevel/.gitmodules submodule.$name.branch)\"; git checkout $branch'"

#sm-pullrebase :
# - pull --rebase on the master repo
# - sm-trackbranch on every submodule
# - pull --rebase on each submodule
#
# Important note :
#- have a clean master repo and subrepos before doing this !
#- this is *not* equivalent to getting the last committed 
#  master repo + its submodules: if some submodules are tracking branches 
#  that have evolved since the last commit in the master repo,
#  they will be using those more recent commits !
#
#  (Note : On the contrary, git submodule update will stick 
#to the last committed SHA1 in the master repo)
#
sm-pullrebase = "! git pull --rebase; git submodule update; git sm-trackbranch ; git submodule foreach 'git pull --rebase' "

# git sm-diff will diff the master repo *and* its submodules
sm-diff = "! git diff && git submodule foreach 'git diff' "

#git sm-push will ask to push also submodules
sm-push = push --recurse-submodules=on-demand

#git alias : list all aliases
#useful in order to learn git syntax
alias = "!git config -l | grep alias | cut -c 7-"
查看更多
余欢
6楼-- · 2018-12-31 02:22

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.

  1. Your .gitmodules has an entry like so:

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
    
  2. 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
    

    EDIT: only branch name is supported above, not SHA or TAG.

    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.

查看更多
登录 后发表回答