我正在只读文件系统中使用 git 管道和镜像(因此是裸露的)存储库。
我可以看到子模块的存在git ls-tree
。我可以推断出它们的名称/路径和 SHA1,但我找不到获取子模块远程的方法。
信息在某处;如果我克隆回购,git submodule init
成功。(克隆对于正常使用来说太昂贵了,特别是对于非常大的存储库。)我怎样才能直接访问子模块远程?
我正在只读文件系统中使用 git 管道和镜像(因此是裸露的)存储库。
我可以看到子模块的存在git ls-tree
。我可以推断出它们的名称/路径和 SHA1,但我找不到获取子模块远程的方法。
信息在某处;如果我克隆回购,git submodule init
成功。(克隆对于正常使用来说太昂贵了,特别是对于非常大的存储库。)我怎样才能直接访问子模块远程?
git config --blob HEAD:.gitmodules --list
从那里开始。这需要 Git 版本 >= 1.8.4。请注意,HEAD
可以是任何修订版。
评论变成了答案,大部分答案由 OP 提供。:-) 此外,我们有以下自引用定义:超级项目是具有子模块的 Git 存储库,子模块(有时也称为子项目)是由超级项目控制的 Git 存储库。子模块本身通常在特定提交时保持签出(即,作为“分离的 HEAD”),尽管现在有一些特殊情况可以指示 Git 将子模块切换到命名分支。如果一个子模块有更多的子模块,则“外部”子模块是“内部”子模块的超级项目,因此 super/sub 都是相对的。
子模块——存储库 URL 及其检出路径——由超级项目.gitmodules
根目录中的一个文件提供。因此,在裸存储库中,您将获取或提取.gitmodules
文件。该文件被格式化为配置文件,因此可以通过git config --file
.
从 Git 2.0 版本开始,您可以使用伪名称-
来引用标准输入,因此:
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 或类似的东西)。
由于 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
在子模块的目录中执行并获取其来源的 urlgit submodule update --init
)