首页/开发/Git 与协作速查/CI 中拉取子模块
进阶与大仓实践69 条

CI 中拉取子模块

流水线默认浅克隆不含子模块:需要 --recurse-submodules 并按需加深历史;私有子模块要在同一凭据体系下可访问,否则构建会卡在拉取。

Git 与协作速查开发更新于 2026-10-13

CI 中拉取子模块是什么

流水线里的默认克隆往往不含子模块、且只有浅历史:要用 --recurse-submodules 让克隆带上子模块、--shallow-submodules 控制每层深度;私有子模块必须与父仓库在同一套只读凭据下可见,否则构建会卡在拉取子模块这一步,报错信息还常常指向缺文件而不是权限。

基本信息

一步克隆git clone --recurse-submodules --shallow-submodules --depth 1 <url>
已克隆补齐git submodule update --init --recursive --depth 1
权限子模块与父仓库需同一套只读凭据(部署密钥/令牌)
校验git -C app submodule status --recursive,行首全为空格即拉齐
连通性SSH 地址先 ssh -T 验证密钥;HTTPS 用令牌并确认无交互提示

典型使用场景

  • 全新流水线检出:一条命令带齐所有子模块,不用在构建脚本里补拉。
  • 已有工作区补拉:父仓库已克隆后用 update --init --recursive 把子模块补上。
  • 控制耗时:子模块只需当前提交时加 --depth 1 与 --shallow-submodules。
  • 私有子模块:逐个核对部署密钥对每个子模块仓库都有读权限,缺一不可。
  • 历史版本构建:构建旧 tag 时确认子模块对应提交在上游仍可获取。
  • 缓存场景:缓存键若只覆盖父仓库内容,恢复后子模块可能是旧指针,纳入校验再决定是否复用缓存。

CI 常用写法

CI 常用写法
git clone --recurse-submodules --shallow-submodules --depth 1 https://example.com/app.git
# 一步带齐子模块,每层只取最新提交,节省流水线时间
git -C app submodule status --recursive   # 校验:所有行首都应是空格
git -C app submodule update --init --recursive --depth 1   # 已克隆仓库补拉
ssh -T git@example.com                    # 子模块走 SSH 时先验证密钥连通性
私有子模块漏授权是最常见的失败:先手工单独克隆一次子模块仓库验证凭据,再回到流水线比对;报错停在 Cloning into 且长时间不动,多半是在等待凭据输入。

易错点

  • 只克隆父仓库时子模块目录为空,构建报错常指向缺文件而不是子模块本身,先跑 submodule status 再排查构建脚本。
  • 子模块指向的提交被上游 force push 删除后拉取必失败,需要先把指针修到可达提交再重跑流水线。
  • 私有子模块与父仓库凭据不互通时会卡住或报 403,逐个仓库验证读取权限,不要指望一个密钥通吃;授权清单用脚本批量校验更省事。
  • 浅克隆子模块后仍依赖完整历史的步骤会失败:缓存或构建脚本按需加深,不要无脑全局 unshallow。
  • 凭据配置成带交互提示的方式会让无人值守流水线挂起,改用部署密钥或访问令牌并先用 status 校验,通过后再接入正式流水线。

数据来源与参考

  • Git 官方文档:git-submodule(--depth/--shallow-submodules)
  • Git 官方文档:git-clone(--recurse-submodules)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌