我试图设置一个通用的.gitmodules文件,用作新项目总是需要的某些静态数量的子模块的模板。然后使用Restore git submodules from .gitmodules中显示的技术一次性初始化子模块:
#!/bin/sh
#set -e
git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
while read path_key path
do
url_key=$(echo $path_key | sed 's/\.path/.url/')
url=$(git config -f .gitmodules --get "$url_key")
branch_key=$(echo $path_key | sed 's/\.path/.branch/')
branch=$(git config -f .gitmodules --get "$branch_key")
if [ ! -d "$path" ]; then
echo URL - $url, Path - $path, Branch - $branch
if [ -n "$branch" ]; then
branch="-b $branch"
fi
git submodule add --force $branch $url $path
fi
done
但是,似乎无法在.gitmodules文件中指定标记(而不是分支):
[submodule "externals/asio"]
path = externals/asio
url = https://github.com/chriskohlhoff/asio.git
branch = asio-1-11-0
导致:
fatal: Cannot update paths and switch to branch 'asio-1-11-0' at the same time.
Did you intend to checkout 'origin/asio-1-11-0' which can not be resolved as commit?
Unable to checkout submodule 'externals/asio'
完全可以这样做:
cd externals/asio
git co asio-1-11-0
有关如何指定特定标记的任何想法?
Stackoverflow上没有答案我发现,即使是重复项,也显示是否可以在.gitmodules中指定标记。此外,我发现的问题与使用git子模块有关,而不是使用.gitmodules文件从头开始初始化一个repo。
答案 0 :(得分:1)
我认为问题是当前索引尚未拥有子模块。你想要做的是将子模块克隆到 first (使用你认为合适的任何git clone
命令),检查所需的提交(通过任何适当的方式 - 可能是相同的git clone
命令),只有然后 use git submodule add
:
如果< path>存在并且已经是一个有效的Git存储库,然后它就会在没有克隆的情况下进行提交。
换句话说,这将在超级项目的.gitmodules
文件中创建条目,然后将子模块的当前检出的提交哈希ID 添加到超级项目的索引中。你不在这里添加一个分支,你只需添加 - 它使用签出的提交,如一个标记。
您可能希望在所有这些操作结束时运行git submodule absorbgitdirs
,以便所有子模块.git
存储库都迁移到超级项目的.git
目录中。 (没有要求,如果您的Git较旧,则不会absorbgitdirs
。)
子模块检出通常是分离的。也就是说,你在Git存储库中有一个“分离的HEAD”,它是子模块:它的HEAD
文件的内容是构成一个哈希ID的41个字节。
首次运行git submodule update --checkout
时,默认操作为:
.gitmodules
文件中的指令克隆子模块。查看超级项目的gitlink标识的特定提交。这是存储在超级项目的工作树索引中的哈希ID。
(令人讨厌的是,看索引条目有点困难,因此相应的哈希ID。您可以使用git ls-files --stage <path>
或git rev-parse :0:<path>
来查看它。 -end接口git show
,无法显示子项目提交哈希值!这似乎是一个错误。)
无论是否存在分支设置,都会发生这种情况。使用git submodule update --rebase
或git submodule update --merge
时,分支设置开始变得重要。
您还可以将submodule.name.update
设置为checkout
,rebase
或merge
,在这种情况下,git submodule update --init
会遵守您在此处设置的内容。然后分支设置将再次重要。但如果您没有设置,git submodule update --init
默认为git submodule update --checkout
。
通过哈希ID检出特定提交会导致分离的HEAD。
按名称检出标记会导致分离的HEAD,特别是标记名称解析的哈希ID。
标签名称永远不会改变。假设这是真的。这意味着如果您将gitlink中的原始哈希ID记录为标记名称解析的哈希ID,git submodule update
操作将导致检出相同的提交哈希ID ,使用相同的分离的HEAD,检查标记。因此,此处没有 need 来设置标记名称,因此根本不要使用-b <branch>
选项。