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版本。
当前回答
为子模块选择分支的唯一效果是,每当你在git子模块更新命令行中传递——remote选项时,git将以分离HEAD模式(如果选择默认的——checkout行为)检出所选远程分支的最新提交。
You must be particularly careful when using this remote branch tracking feature for Git submodules if you work with shallow clones of submodules. The branch you choose for this purpose in submodule settings IS NOT the one that will be cloned during git submodule update --remote. If you pass also the --depth parameter and you do not instruct Git about which branch you want to clone -- and actually you cannot in the git submodule update command line!! -- , it will implicitly behave like explained in the git-clone(1) documentation for git clone --single-branch when the explicit --branch parameter is missing, and therefore it will clone the primary branch only.
毫无疑问,在git子模块update命令执行克隆阶段之后,它最终将尝试检出之前为子模块设置的远程分支的最新提交,如果这不是主分支,那么它就不是本地浅克隆的一部分,因此它将失败
致命的:需要一次修改 无法在子模块路径“mySubmodule”中找到当前的origin/NotThePrimaryBranch修订
其他回答
Git子模块有点奇怪——它们总是处于“分离头”模式——它们不会像你期望的那样更新到分支上的最新提交。
不过,当你仔细思考时,这确实是有道理的。假设我用子模块bar创建了存储库foo。我推送我的更改并告诉您从存储库foo中提交a7402be。
然后想象一下,在您可以克隆之前,有人将更改提交到存储库栏。
当您从存储库foo签出commit a7402be时,您希望得到与我推送的相同的代码。这就是为什么子模块不会更新,直到你显式地告诉它们,然后进行新的提交。
我个人认为子模块是Git中最令人困惑的部分。有很多地方可以比我更好地解释子模块。我推荐Scott Chacon的Pro Git。
根据我的经验,在超级项目或未来的签出中切换分支仍然会导致子模块的头部分离,无论子模块是否正确添加和跟踪(即@djacobs7和@Johnny Z答案)。
而不是手动签出正确的分支手动或通过脚本git子模块foreach可以使用。
这将检查子模块配置文件中的分支属性并检出set分支。
Git子模块foreach -q——recursive 'branch="$(Git config -f $ topllevel . "gitmodules子模块。name.branch美元)”;Git checkout $branch'
我的.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子模块add -b develop——name branch-name——https://branch.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
也许它有帮助(即使我使用标记而不是分支)?