如何在gitmodules文件中指定标记?

如何在gitmodules文件中指定标记?,git,Git,我正在尝试设置一个generic.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/')

我正在尝试设置一个generic.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文件来初始化从头开始的回购。

我认为您需要的答案(逻辑上,这将在下一节之后) 我想问题在于当前索引中还没有子模块。您要做的是首先将子模块克隆到位(使用您认为合适的任何
git clone
命令),检查所需的提交(通过任何合适的方式,可能是相同的
git clone
命令),然后:

如果存在并且已经是一个有效的Git存储库,那么它将在不进行克隆的情况下进行提交

换句话说,这将在超级项目的
.gitmodules
文件中创建条目,然后将子模块当前签出的提交哈希ID添加到超级项目的索引中。这里不需要添加分支,只需添加使用签出提交的分支,就像添加标记一样

您可能希望在所有这一切结束时运行
git子模块absorbgitdirs
,以便所有子模块
.git
存储库迁移到超级项目的
.git
目录中。(对此没有要求,如果您的Git较旧,它将不会有
absorbgitdirs

设置:或者,如果上述内容没有意义,请先阅读此内容 子模块签出通常是分离的。也就是说,在Git存储库中有一个“分离的头”,即子模块:它的
头文件的内容是构成散列ID的41个字节

当您第一次运行git子模块更新--checkout时,默认操作是:

  • 如果需要,使用超级项目中
    .gitmodules
    文件中的指令克隆子模块

  • 检查超级项目的gitlink标识的特定提交。这是存储在超级项目工作树索引中的哈希ID

    (令人烦恼的是,要查看索引项以及相应的哈希ID有点困难。您可以使用
    git ls files--stage
    git rev parse:0:
    来查看它。漂亮的前端接口,
    git show
    ,无法显示子项目提交哈希!这似乎是个bug。)

  • 无论是否存在分支设置,都会发生这种情况。随着
    git子模块更新--rebase
    git子模块更新--merge
    ,分支设置开始起作用

    您还可以将
    submodule.name.update
    设置为
    checkout
    rebase
    、或
    merge
    ,在这种情况下,
    git submodule update--init
    遵循您在此处设置的内容。然后,分支设置将再次起作用。但是如果您不设置它们,
    git submodule update--init
    默认为
    git submodule update--checkout

    通过散列ID签出特定的提交将导致分离的头

    按名称签出标记也会导致分离的头,特别是标记名解析到的哈希ID


    标签名永远不会改变。假设这是真的。这意味着,如果您在gitlink中记录标记名解析到的散列ID作为原始散列ID,
    git子模块更新
    操作将导致签出与签出标记相同的提交散列ID,具有相同的分离头。因此,这里不需要设置标签名,所以根本不要使用
    -b
    选项。

    可能重复@GolezTrol。不幸的是,我在那里找不到答案……答案似乎是不可能。因此,如果子模块更新失败,我选择恢复到签出标记。这似乎很好。谢谢,我最终是这样做的:拥有一个“模板”模块文件(指定了分支和标记),然后解析该文件并设置子模块结构,根据需要对添加的子模块进行签出。它是最简洁的。OP的问题的答案是:无法在.gitmodules中指定标记。您不能在
    .gitmodules
    中指定标记:这没关系,因为提交指定了哈希ID,这同样好。