【问题标题】:git plumbing command to get submodule remotegit管道命令获取子模块远程
【发布时间】:2017-05-03 22:34:06
【问题描述】:

我正在一个只读文件系统中使用 git 管道和镜像(因此是裸露的)存储库。

我可以看到带有git ls-tree 的子模块的存在。我可以推断出它们的名称/路径和 SHA1,但我找不到获取子模块远程的方法。

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

【问题讨论】:

  • 它在.gitmodules 具有配置文件格式的文件中,因此如果您提取文件,您可以在其上使用git config -f(又名--file)。不过,这本身有点棘手。 git show <rev>:.gitmodulesgit cat-file -p <rev>:.gitmodules 将获取内容。如果你有/dev/stdin,你可以通过管道将它们发送到git config -f /dev/stdin
  • @torek 你会把它变成一个答案,这样我就可以接受了吗?这正是我想要的。
  • 我可以,但我不确定你需要从.gitmodules 文件中提取什么(即,你需要什么git config -f ... --get
  • 没关系。关键是知道数据隐藏在哪里。弄清楚格式很容易。 :) 看起来您搜索 submodule.<name>.path=<path> 其中 是您要匹配的路径。这告诉你。然后查找submodule.<name>.url=<url>,一切就绪。

标签: git git-submodules git-plumbing


【解决方案1】:

总结

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

详细说明和解释

评论变成了答案,大部分答案由 OP 提供。 :-) 此外,我们有以下自引用定义:superproject 是一个具有子模块的 Git 存储库,以及一个 submodule(有时也称为 subproject ) 是一个由超级项目控制的 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.<em>name</em>.path 设置为 P 的条目。该子模块的 URL 为 submodule.<em>name</em>.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 或类似的东西)。

【讨论】:

    【解决方案2】:

    从 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 并获取它们的来源网址

    注意

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

    【讨论】:

      猜你喜欢
      • 2017-07-06
      • 2020-08-16
      • 1970-01-01
      • 1970-01-01
      • 2018-01-06
      • 1970-01-01
      • 1970-01-01
      • 2015-11-25
      • 2012-03-15
      相关资源
      最近更新 更多