git plumbing命令获取子模块远程

时间:2016-12-18 21:22:48

标签: git git-submodules git-plumbing

我正在使用git plumbing和镜像(以及裸露的)repos,在一个只读的文件系统中。

我可以看到存在具有git ls-tree的子模块。我可以推断出他们的名字/路径和SHA1,但我找不到让子模块远程的方法。

信息在某处;如果我克隆了回购,git submodule init成功。 (使克隆对于正常使用来说太昂贵了,特别是对于非常大的存储库。)如何直接进入子模块远程?

2 个答案:

答案 0 :(得分:5)

摘要

git config --blob HEAD:.gitmodules --list开始,然后从那里开始。这需要Git版本> = 1.8.4。请注意,HEAD可以是任何修订版。

长篇和解释

评论变成了答案,OP提供了大部分答案。 :-)另外,我们有以下自引用定义: superproject 是一个包含子模块的Git存储库,以及一个子模块(有时也称为子项目)是由超级项目控制的Git存储库。子模块本身通常在特定提交时保持签出(即,作为"分离的HEAD"),尽管现在有特殊情况可以指示Git将子模块切换到命名分支。如果一个子模块有更多的子模块,那么"外部"子模块是"内部"的超级项目。子模块,所以super / sub都是相对的。

子模块 - 存储库URL及其签出路径 - 由超级项目根目录中名为.gitmodules的文件提供。因此,在裸存储库中,您将获取或提取.gitmodules文件。此文件格式化为配置文件,因此可通过git config --file读取。

从Git 2.0版开始,你可以使用伪名-来引用stdin,所以:

git show HEAD:.gitmodules | git config --file - --list

将以熟悉的格式转储内容。 (如果您的Git变体早于此版本,但您拥有/dev/stdin,则可以在此处阅读/dev/stdin。)

事实证明,有一种更简单的方法:git config可以,因为Git版本1.8.4,直接读取存储库中的blob。 blob标识符是git rev-parse可接受的任何内容,它不仅可以处理分支名称或提交ID,还可以处理后续路径名称。 (此代码专门用于子模块处理:请参阅commit 1bc888193e1044db317a45b9a4c8d2b87b998f40。)

详细信息

给定子模块路径 P ,子模块的名称是submodule.name.path设置为 P 的条目。然后,该子模块的URL为submodule.name.url

可以使用git config --get-regexp搜索到所需的名称。但是,它充其量是烦人的,因为我们必须引用正则表达式元字符的路径名组件,明显常见的是.

$ git config --blob HEAD:.gitmodules \
    --get-regexp 'submodule\..*\.path' 'some/dir\.name/path'
submodule.foo.path some/dir.name/path

因此,仅使用--list转储配置并使用其他内容来提取有趣的字段可能更有意义。例如:

git config --blob HEAD:.gitmodules --list | \
    awk -F= -vpath='some/dir.name/path' \
    '$1 ~ /submodule\..*\.path/ && $2 == path { split($1, a, "."); print a[2] }'

(虽然当你把它放到可以读取寻找gitlinks的树的东西时,你可能想要Python或其他一些东西)。

答案 1 :(得分:0)

从git v2.x开始,您可以使用以下代码:

git config --file .gitmodules --get-regexp 'submodule\.\S+\.path' | 
    awk '{print $2}' |
    xargs -i git -C {} remote get-url origin

说明

  • 第一个和第二个命令返回所有子模块的相对路径
  • 第3条命令在子模块的目录中执行git remote并获取其来源的网址

NB

  • 子模块的远程名称应为“ origin”(由git设置为默认远程名称)
  • 子模块应该已经预先初始化(例如,通过在超级项目中执行git submodule update --init