【问题标题】:Automatically access git submodules via ssh or https通过 ssh 或 https 自动访问 git 子模块
【发布时间】:2025-12-19 21:55:07
【问题描述】:

问题:
有没有办法通过与主存储库相同的方法(ssh 或 https)自动检出 git 子模块?

背景:

我们有一个非公共 gitlab 存储库 (main),它有一个子模块 (utils),它也作为非公共 gitlab 存储库托管在同一台服务器上。可以通过 ssh 或 https 访问这些存储库:

  • user@gitlabserver.com:my/path/repo.git
  • https://gitlabserver.com/my/path/repo.git

显然,这两种变体都需要不同形式的身份验证,并且取决于客户端计算机和用户,首选其中一种。

对于*存储库 (main) 这不是问题,因为任何人都可以选择他或她喜欢的方法,但对于子模块,这取决于 .gitmodules 文件,因此(最初)是所有人都一样。
现在,每个人都不必将 .gitmodules 文件调整为他们喜欢的任何内容并确保他们不会意外提交这些更改,如果有一种方法可以只指定服务器和 repo 路径并且 git 选择与主 repo 使用的方法相同,或者可以在 gitconfig 中设置的方法。

【问题讨论】:

  • tldr 抱歉。但我使用 git-hooks 运行 git submodule foreach git submodule update 或类似的。我没有时间写一个正确的答案,但我希望这会有所帮助。

标签: git gitlab git-submodules


【解决方案1】:

我终于通过将子模块 url 指定为relative path 解决了这个问题:

假设可以访问您的主 git 存储库

  • 通过https://gitlabserver.com/my/path/main.git
  • 或通过user@gitlabserver.com:my/path/main.git

.gitmodules 文件如下所示:

[submodule "utils"]     
    path = libs/utils   
    url = https://gitlabserver.com/my/path/utils.git

这意味着即使您通过 ssh 签出主应用程序,子模块 utils 仍然可以通过 https 访问。

但是,您可以用这样的相对路径替换绝对路径:

[submodule "utils"]     
    path = libs/utils   
    url = ../utils.git

从现在开始使用

  • git clone --recursive https://gitlabserver.com/my/path/main.git
  • git clone --recursive user@gitlabserver.com:my/path/main.git

以您想要的方式获得整个存储库结构。显然,这不适用于相对 ssh 和 https 路径不相同的情况,但至少对于 gitlab 托管的存储库是这样。

如果您(无论出于何种原因)在两个不同的远程站点镜像您的存储库结构,这也很方便。

【讨论】:

  • 如果模块指向不同的存储库,这也不起作用,对吧?例如,如果这是中心项目 username@stash.company.net/abc/win/win-agent.git 而这是一个引用模块 username@stash.company.net/abc/mob/module.git
  • @David:我无法测试它,但我不明白为什么它不起作用(显然在这种情况下你必须使用../../mob/module.git)。
  • 我用 ../ 对其进行了测试,但更新并没有失败,但对我来说似乎不合逻辑,它不应该工作,它应该只与 ../../ 一起工作写的。
  • 好的,以下工作:根项目 username@stash.company.net/scm/win/win-agent.git 引用模块 username@stash.company.net/scm/mob/module.git 与以下配置: [子模块“模块/模块”] 路径 = 模块/模块 url = ../../mob/module.git
  • 谢谢你,在更改.gitmodules 之后,我必须做的另一件事是运行; git submodule sync(参考;dhoeric.github.io/2017/https-to-ssh-in-gitmodules
【解决方案2】:

我想我有一个更笼统的答案,但它不是完全自动的。您可以在 ~/.gitconfig 中应用一个配置设置,它将用您选择的 URL 替换特定的 URL。

对于Github,我的~/.gitconfig 中有这个:

[url "ssh://git@github.com/"]
    insteadOf = https://github.com/

这是一个存储库,其中包含一个使用 HTTPS url 声明的子模块,我可以使用 HTTPS 递归地克隆它。

git clone --recursive https://github.com/p2/OAuth2.git

git clone --recursive git@github.com:p2/OAuth2.git

您可以在此处阅读有关其用途的信息:https://git-scm.com/docs/git-config#Documentation/git-config.txt-urlltbasegtinsteadOf

在这里:https://git-scm.com/docs/git-clone

【讨论】:

  • 谢谢。该设置看起来非常有用。我仍然希望尽可能使用相对路径,因为我可以告诉其他人递归地克隆存储库 X,而无需进一步手动配置。但是,从另一端来看,这似乎很完美:我想克隆其他人的存储库树,该存储库树不使用与作者预期不同的方法(或镜像)的相对路径。
  • 当然,如果你不能总是使用相对路径。
  • 当然可以。我注意到这在 XCode 和 Swift 包管理器中效果不佳,但相关子模块也不是。