git子模块add -b如何工作?

在添加带有特定分支的子模块后,一个新的克隆存储库(在git子模块update——init之后)将在特定的提交处,而不是分支本身(子模块上的git状态显示为“not current on any branch”)。

我在.gitmodules或.git/config中找不到任何关于子模块分支或任何特定提交的信息,那么Git是如何解决的呢?

另外,是否可以指定一个标记而不是分支?

我使用的是1.6.5.2版本。


当前回答

我的.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-"

其他回答

我的.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 1.8.2增加了跟踪分支的可能性。下面是一些答案。


习惯这一点有点令人困惑,但子模块并不在分支上。正如您所说,它们只是指向子模块存储库的特定提交的指针。

这意味着,当其他人签出你的存储库,或提取你的代码,并进行git子模块更新时,子模块将被签出到特定的提交。

这对于不经常更改的子模块非常有用,因为这样项目中的每个人都可以在同一次提交时拥有子模块。

如果你想移动子模块到一个特定的标签:

cd submodule_directory
git checkout v1.0
cd ..
git add submodule_directory
git commit -m "moved submodule to v1.0"
git push

然后,另一个希望将submodule_directory更改为该标记的开发人员执行此操作

git pull
git submodule update --init

Git拉修改提交他们的子模块目录指向。Git子模块update实际上合并到新代码中。

根据我的经验,在超级项目或未来的签出中切换分支仍然会导致子模块的头部分离,无论子模块是否正确添加和跟踪(即@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子模块

为了切换子模块的分支(假设你已经将子模块作为存储库的一部分):

CD到包含子模块的存储库的根目录 打开.gitmodules进行编辑 在path =…url =…对于每个子模块,它说branch = your-branch;保存文件。gitmodules。 然后在不改变目录的情况下执行$ git子模块update——remote

...对于这样修改的每个子模块,这应该拉入指定分支上的最新提交。