我在只读文件系统中使用git plumbing和镜像(因此是裸机)存储库。
我可以看到带有的子模块git ls-tree
。我可以推断出它们的名称/路径和SHA1,但是找不到找到远程子模块的方法。
信息在某处。如果我克隆回购协议,那就git submodule init
成功了。(进行克隆对于正常使用而言太昂贵了,特别是对于非常大的存储库而言。)如何直接从远程获得子模块?
开始git config --blob HEAD:.gitmodules --list
从那里走。这需要Git版本> = 1.8.4。请注意,HEAD
可以是任何版本。
评论变成了答案,OP提供了很多答案。:-)另外,我们有以下自引用定义:超级项目是具有子模块的Git存储库,子模块(有时也称为子项目)是由超级项目控制的Git存储库。尽管现在在某些特殊情况下,您可以指示Git将子模块切换到命名分支,但通常会在特定的提交(例如,作为“分离的HEAD”)中将子模块本身保持检出状态。如果子模块还有其他子模块,则“外部”子模块是“内部”子模块的超级项目,因此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,子模块的名称是设置为P的任何条目。该子模块的URL为。submodule.name.path
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] }'
(尽管当您将其放入可以读取树以查找gitlink的对象中时,您可能想要Python或类似的东西)。