我正在使用git plumbing和镜像(以及裸露的)repos,在一个只读的文件系统中。
我可以看到存在具有git ls-tree
的子模块。我可以推断出他们的名字/路径和SHA1,但我找不到让子模块远程的方法。
信息在某处;如果我克隆了回购,git submodule init
成功。 (使克隆对于正常使用来说太昂贵了,特别是对于非常大的存储库。)如何直接进入子模块远程?
答案 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
git remote
并获取其来源的网址git submodule update --init
)