主仓库成功克隆并不能测试它的子模块。子模块是另一个 Git 仓库,可能位于不同主机,也可能使用不同传输方式。

先读取已声明的 URL:

git -C project config --file .gitmodules --get-regexp '^submodule\..*\.url$'
git -C project submodule status --recursive

通过 HTTPS 获取的父仓库可能包含使用 git@host: 的子模块。HTTP 代理设置不会配置这条 SSH 连接。相对的子模块 URL 也必须根据超级项目的正确远程仓库解析,而不是根据项目名称臆测的某个网页地址。

仓库本地设置有自己的作用范围

本地 http.proxy 条目属于包含该配置文件的仓库。不要以为只检查父仓库,就能看到初始化后的子仓库实际使用的全部有效设置。

要在递归更新期间临时覆盖 HTTPS 代理,可以把 Git 命令行配置传给这次调用:

git -C project -c http.proxy=http://203.0.113.10:8080 \
  submodule update --init --recursive

替换示例端点。对于允许使用公共代理的公共 HTTPS 子模块,HTTP 代理列表提供候选地址。这不会把子模块的 SSH URL 转成 HTTPS;选定的路由令人意外时,也要检查更具体的 URL 配置。

记录的 URL 发生变化时

Git 会在初始化期间把子模块配置登记到本地。如果项目中的子模块 URL 已改变,先把当前声明与本地登记值比较,再判断代理是否失效。文档中的同步操作会根据项目声明更新登记的 URL;它本身不是网络代理设置。

遇到嵌套失败时,记下错误中出现的确切子模块路径和远程仓库。递归操作可能联系多个主机;内部主机可能需要直连例外,而公共主机使用代理。

将传输错误与仓库错误分开。提交不可用、仓库拒绝访问、连接代理失败,是同一个“子模块更新失败”结果背后的不同原因。

相关文章