Iva*_*van 698 git git-submodules
git submodule add -b工作怎么样?
添加具有特定分支的子模块后,新的克隆存储库(之后git submodule update --init)将处于特定提交,而不是分支本身(git status在子模块上显示"当前不在任何分支上").
我无法找到任何信息.gitmodules或.git/config关于子模块的分支或任何具体的承诺,那么,如何Git的数字出来?
此外,是否可以指定标签而不是分支?
我正在使用1.6.5.2版.
dja*_*bs7 703
注意: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
Run Code Online (Sandbox Code Playgroud)
然后,另一个想要将submodule_directory更改为该标记的开发人员执行此操作
git pull
git submodule update --init
Run Code Online (Sandbox Code Playgroud)
git pull提交其子模块目录的更改. git submodule update实际上合并在新代码中.
Joh*_*y Z 591
我想在这里添加一个答案,它实际上只是其他答案的集合,但我认为它可能更完整.
当你有这两件事时,你知道你有一个Git子模块.
你.gitmodules有这样的条目:
[submodule "SubmoduleTestRepo"]
path = SubmoduleTestRepo
url = https://github.com/jzaccone/SubmoduleTestRepo.git
Run Code Online (Sandbox Code Playgroud)您的Git存储库中有一个子模块对象(在此示例中名为SubmoduleTestRepo).GitHub将这些显示为"子模块"对象.或者git submodule status从命令行执行.Git子模块对象是特殊类型的Git对象,它们保存特定提交的SHA信息.
无论何时执行git submodule update,它都会使用提交中的内容填充子模块.它知道在哪里找到提交,因为中的信息.gitmodules.
现在,所有-b操作都是在您的.gitmodules文件中添加一行.所以按照相同的例子,它看起来像这样:
[submodule "SubmoduleTestRepo"]
path = SubmoduleTestRepo
url = https://github.com/jzaccone/SubmoduleTestRepo.git
branch = master
Run Code Online (Sandbox Code Playgroud)
编辑:上面只支持分支名称,而不是SHA或TAG.
子模块对象仍指向特定的提交.根据Vogella的回答,该.gitmodules选项购买的唯一功能是能够git add .为您的更新添加标记:
git submodule update --remote
Run Code Online (Sandbox Code Playgroud)
它不是将子模块的内容填充到子模块指向的提交中,而是用主分支上的最新提交替换该提交,然后用该提交填充子模块.这可以通过djacobs7回答分两步完成.由于您现在已经更新了子模块对象所指向的提交,因此您必须将更改的子模块对象提交到Git存储库中.
git add ./SubmoduleTestRepo并不是一些神奇的方法来保持一切与分支最新.它只是添加有关.gitmodules文件中某个分支的信息,并为您提供了在填充之前将子模块对象更新为指定分支的最新提交的选项.
Von*_*onC 310
请注意,如果您现有的子模块尚未跟踪分支,那么(如果您有git 1.8.2+):
确保父repo知道它的子模块现在跟踪一个分支:
cd /path/to/your/parent/repo
git config -f .gitmodules submodule.<path>.branch <branch>
Run Code Online (Sandbox Code Playgroud)确保您的子模块实际上是该分支的最新部分:
cd path/to/your/submodule
git checkout -b branch --track origin/branch
# if the master branch already exist:
git branch -u origin/master master
Run Code Online (Sandbox Code Playgroud)
(与"原点"是的名称上游远程回购子模块已从.克隆
甲git submodule set-branch --branch aBranch -- <submodule_path>内部的子模块将其显示.通常,它是"原点")
不要忘记在父仓库中记录子模块的新状态:
cd /path/to/your/parent/repo
git add path/to/your/submodule
git commit -m "Make submodule tracking a branch"
Run Code Online (Sandbox Code Playgroud)该子模块的后续更新必须使用以下git remote -v选项:
# update your submodule
# --remote will also fetch and ensure that
# the latest commit from the branch is used
git submodule update --remote
# to avoid fetching use
git submodule update --remote --no-fetch
Run Code Online (Sandbox Code Playgroud)请注意,使用Git 2.10 +(2016年第3季度),您可以使用' --remote'作为分支名称:
分支的名称记录
.在submodule.<name>.branch了.gitmodules.
特殊值update --remote用于指示子模块中分支的名称应与当前存储库中当前分支的名称相同.
如果要更新分支后的所有子模块:
git submodule update --recursive --remote
Run Code Online (Sandbox Code Playgroud)
请注意,对于每个更新的子模块,结果几乎总是一个独立的HEAD,正如Dan Cameron在他的回答中所说.
(Clintm notes in the comments that, if you run . and the resulting sha1 is the same as the branch the submodule is currently on, it won't do anything and leave the submodule still "on that branch" and not in detached head state.)
To ensure the branch is actually checked out (and that won't modify the SHA1 of the special entry representing the submodule for the parent repo), he suggests:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git checkout $branch'
Run Code Online (Sandbox Code Playgroud)
每个子模块仍将引用相同的SHA1,但是如果您确实进行了新的提交,则可以推送它们,因为它们将由您希望子模块跟踪的分支引用.
在子模块中推送之后,不要忘记返回到父repo,添加,提交并推送新的SHA1用于那些已修改的子模块.
使用注意事项git submodule update --remote,建议在评论由亚历山大Pogrebnyak.
$toplevel于2010年5月在git1.7.2中引入:提交f030c96.
它包含顶级目录的绝对路径(在哪里
$toplevel).
foreach脚本将无法签出不在分支之后的子模块.
但是,此命令为您提供:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch' –
Run Code Online (Sandbox Code Playgroud)
相同的命令,但更容易阅读:
git submodule foreach -q --recursive \
'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
[ "$branch" = "" ] && \
git checkout master || git checkout $branch' –
Run Code Online (Sandbox Code Playgroud)
umläute 在评论中用简化版改进了dtmland的命令:
git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
Run Code Online (Sandbox Code Playgroud)
多行:
git submodule foreach -q --recursive \
'git checkout \
$(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
Run Code Online (Sandbox Code Playgroud)
vog*_*lla 193
Git 1.8.2增加了跟踪分支的可能性.
# add submodule to track master branch
git submodule add -b branch_name URL_to_Git_repo optional_directory_rename
# update your submodule
git submodule update --remote
Run Code Online (Sandbox Code Playgroud)
另请参见Git子模块
Joh*_*han 53
我如何使用Git子模块的一个例子.
这看起来有点像这样:
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
Run Code Online (Sandbox Code Playgroud)
也许它有帮助(即使我使用标签而不是分支)?
Dmi*_*kiy 53
现有的答案缺少第二步,并且细节过多。
要切换现有子模块以跟踪新的远程 url 和/或新分支:
.gitmodules。例如,从
[submodule "api"]
path = api
url = https://github.com/<original_repo>/api.git
Run Code Online (Sandbox Code Playgroud)
到
[submodule "api"]
path = api
url = https://github.com/<another_repo>/api.git
branch = work-in-progress
Run Code Online (Sandbox Code Playgroud)
您还可以用于hexsha提交哈希。或者tag,但参见 3。
git submodule sync.git/modules:根据 中指定的刚刚编辑的真实来源更新 git 缓存的子模块的描述.gitmodules。
仅当您指定标签时:git submodule foreach --recursive 'git fetch --tags'才能获取标签。
git submodule update --init --recursive --remote:更新工作副本中签出的子模块。
提交更改。
小智 37
In my experience switching branches in the superproject or future checkouts will still cause detached HEADs of submodules regardless if the submodule is properly added and tracked (i.e. @djacobs7 and @Johnny Z answers).
而不是手动或通过脚本手动检出正确的分支git子模块foreach可以使用.
这将检查分支属性的子模块配置文件并检查set分支.
git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'
Nea*_*all 32
Git子模块有点奇怪 - 它们总是处于"独立头"模式 - 它们不会像您期望的那样更新到分支上的最新提交.
不过,当你考虑它时,这确实有些意义.假设我使用子模块栏创建存储库foo.我推动我的更改,并告诉你检查从存储库foo提交a7402be .
然后想象有人在您进行克隆之前将更改提交到存储库栏.
当您从存储库foo中检出提交a7402be时,您希望得到我推送的相同代码.这就是为什么子模块在您明确告诉它们然后进行新提交之前不会更新的原因.
我个人认为子模块是Git最容易混淆的部分.有很多地方可以比我更好地解释子模块.我推荐Scott Chacon的Pro Git.
Eng*_*eer 17
要切换子模块的分支(假设您已将子模块作为存储库的一部分):
cd 到包含子模块的存储库的根目录.gitmodules进行编辑path = ...和url = ...,说branch = your-branch,对每个子模块; 保存文件.gitmodules.$ git submodule update --remote...这应该为每个被修改的子模块提取指定分支上的最新提交.
我在.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-"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
461725 次 |
| 最近记录: |