关于git:如何在gitmodules文件中指定标签?


How to specify a tag in gitmodules file?

我正在尝试设置一个通用的.gitmodules文件,作为新项目总是需要的某些静态子模块的模板。然后使用restore git submodules from.gitmodules中所示的技术一次性初始化子模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/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文件中指定标记(而不是分支):

1
2
3
4
[submodule"externals/asio"]
    path = externals/asio
    url = https://github.com/chriskohlhoff/asio.git
    branch = asio-1-11-0

结果是:

1
2
3
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'

不过,完全有可能做到这一点:

1
2
cd externals/asio
git co asio-1-11-0

关于如何指定一个特定的标签有什么想法吗?

我在stackoverflow上没有找到任何答案,即使是建议的重复项,也会显示是否可以在.gitmodules中指定标记。另外,我发现的问题与使用git子模块有关,而不是使用.gitmodules文件从头初始化repo。


我认为你需要的答案是什么(从逻辑上讲,这在下一节之后)

我想问题是目前的指数还没有包含子模。您要做的是首先将子模块克隆到适当的位置(使用您认为适当的任何git clone命令),检查所需的提交(通过任何适当的方法,可能是相同的git clone命令),然后才使用git submodule add

If exists and is already a valid Git repository, then it is staged for commit without cloning.

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

您可能希望在所有这些操作结束时运行git submodule absorbgitdirs,以便所有子模块.git存储库都迁移到超级项目的.git目录中。(这是没有要求的,如果你的Git是老的,它就不会有absorbgitdirs。)

设置:或者,如果上面没有任何意义,请先阅读此内容

子模块签出通常是分离的。也就是说,在git存储库中有一个"分离的头",它是子模块:它的HEAD文件的内容是组成散列ID的41个字节。

首次运行git submodule update --checkout时,默认操作是:

  • 如果需要,使用超级项目中.gitmodules文件中的指令克隆子模块。
  • 查看由超级项目的Gitlink标识的特定提交。这是存储在超级项目工作树索引中的哈希ID。

    (令人恼火的是,很难看到索引项,因此也很难看到相应的哈希ID。您可以使用git ls-files --stage git rev-parse :0:来查看它。漂亮的前端接口,git show不能显示子项目提交哈希!这看起来像个虫子。)

  • 不管是否有分支设置,都会发生这种情况。使用git submodule update --rebasegit submodule update --merge时,分支设置开始起作用。

    您也可以将submodule.name.update设置为checkoutrebasemerge,在这种情况下,git submodule update --init服从您在此处设置的任何内容。然后分支设置将再次重要。但是如果你不设置,git submodule update --init默认为git submodule update --checkout

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

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

    标签名不应该改变。假设这是真的。这意味着,如果将标记名解析到的哈希ID作为Gitlink中的原始哈希ID进行记录,那么git submodule update操作将导致签出与签出标记相同的、具有相同分离头的提交哈希ID。因此,这里不需要设置标记名,因此根本不需要使用-b 选项。