git子模块add -b如何工作?
在添加带有特定分支的子模块后,一个新的克隆存储库(在git子模块update——init之后)将在特定的提交处,而不是分支本身(子模块上的git状态显示为“not current on any branch”)。
我在.gitmodules或.git/config中找不到任何关于子模块分支或任何特定提交的信息,那么Git是如何解决的呢?
另外,是否可以指定一个标记而不是分支?
我使用的是1.6.5.2版本。
git子模块add -b如何工作?
在添加带有特定分支的子模块后,一个新的克隆存储库(在git子模块update——init之后)将在特定的提交处,而不是分支本身(子模块上的git状态显示为“not current on any branch”)。
我在.gitmodules或.git/config中找不到任何关于子模块分支或任何特定提交的信息,那么Git是如何解决的呢?
另外,是否可以指定一个标记而不是分支?
我使用的是1.6.5.2版本。
当前回答
根据我的经验,在超级项目或未来的签出中切换分支仍然会导致子模块的头部分离,无论子模块是否正确添加和跟踪(即@djacobs7和@Johnny Z答案)。
而不是手动签出正确的分支手动或通过脚本git子模块foreach可以使用。
这将检查子模块配置文件中的分支属性并检出set分支。
Git子模块foreach -q——recursive 'branch="$(Git config -f $ topllevel . "gitmodules子模块。name.branch美元)”;Git checkout $branch'
其他回答
Git 1.8.2增加了跟踪分支的可能性。
# add submodule to track branch_name branch
git submodule add -b branch_name URL_to_Git_repo optional_directory_rename
# update your submodule
git submodule update --remote
参见Git子模块
一个我如何使用Git子模块的例子。
创建一个新的存储库 然后将另一个存储库克隆为子模块 然后让该子模块使用一个名为V3.1.2的标记 然后我们承诺。
它看起来有点像这样:
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
也许它有帮助(即使我使用标记而不是分支)?
我的.gitconfig文件中有这个。它仍然是一份草案,但目前证明是有用的。它帮助我总是将子模块重新连接到它们的分支。
[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-"
使用下面的命令
添加子模块(分支-分支)
git submodule add -b stage git@github.optum.com:orgname/${reponame}.git
更新子模块(分支-分支)
######Clone########
> git clone -b master --single-branch --recurse-submodules git@github.com:orgname/project.git
or
> git clone -b stage --single-branch --recurse-submodules git@github.com:orgname/project.git
######Update#######
> git submodule update --remote (only for remote branch -ie master)
or
> git submodule update --recursive --remote
> git submodule update --init --recursive (for remaining branchs)
if you get fatal need single revision error then use below commands:-
before:-
*** stage
remotes/origin/stage**
git branch -a
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/{branch name}
ex:- git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/stage
after:-
*** stage
remotes/origin/HEAD -> origin/stage
remotes/origin/stage**
then
> git reset --hard
#hard reset revisions#
> git submodule foreach git reset --hard origin/develop
> git submodule foreach git pull origin develop
在提交和推送相应的.. 现在子模块将得到更新。
我想在这里补充一个答案,它实际上只是其他答案的综合,但我认为它可能更完整。
有了这两个东西,就有了Git子模块。
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 like git 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.