先确认它确实是子模块
适用于已安装 Git 的 Windows、macOS、Linux,在可信项目的主仓库目录中操作;Windows 可使用 PowerShell 或 Git Bash。下面的只读命令不需要管理员权限。本文没有克隆或修改用户仓库,命令基于官方文档核对。执行前用 git --version 记录版本,选项以本机 git submodule -h 为准。
git --version
git status --short --ignore-submodules=none
git submodule status --recursive- 查看项目根目录的 .gitmodules,核对缺失目录是否对应其中的 path,以及它的 url。子模块名称与目录路径可能不同,不要把两者混用。
- 若没有对应条目,或当前目录不是 Git 工作区,先核对项目的获取和构建说明。普通下载目录、打包产物或需要另行生成的文件不能用子模块命令补齐。
- 主仓库成功但子目录为空,可能只是普通克隆尚未初始化子模块;这与 Git LFS 留下文本指针文件是不同情况。
第一步:读懂状态,先保留已有工作
| git submodule status 前缀 | 含义与处理 |
|---|---|
| - | 尚未初始化;核对地址后可补做初始化 |
| + | 已检出的子模块提交与父仓库索引记录不同;先确认是否为自己正在开发的提交 |
| U | 存在子模块合并冲突;先按项目流程解决冲突 |
| 无上述标志 | 提交对齐仍不等于工作目录无改动,要继续看 git status |
先保存主仓库与子模块里的修改、未跟踪文件和自己创建的提交。对已经初始化的目标子模块,进入其目录再执行 git status --short;存在嵌套子模块时也要逐层确认。若有自己的开发提交,先按项目习惯建立分支或备份,不要直接更新覆盖当前工作。
第二步:只补齐项目要求的提交
git submodule update --init --recursive --checkout该命令初始化需要的子模块,下载缺失提交,并按父仓库要求检出;--recursive 包含嵌套子模块。--checkout 明确选择检出方式,通常使子模块处于 detached HEAD,这是此用法的预期状态,不代表下载失败。不要加 --remote 来“补齐”,因为它会改为跟踪子模块远端分支的提交选择。
项目规模较大、只想处理一个子模块时,在命令最后加上“-- 路径”。例如下方 libs/example 是占位目录,必须换成 .gitmodules 中实际的 path;带空格的路径继续保留引号。网络中断时可以先保留已经下载的内容,处理明确错误后再重试相同命令。
git submodule update --init --recursive --checkout -- "libs/example"第三步:下载失败时,查子模块自己的地址
- 从错误中找出实际失败的子模块和主机名,再对照 .gitmodules 中的 url;已初始化的项目还可能保留本地 URL 配置。相对 URL 的解析与父仓库远程地址有关,不是相对本机当前目录随意拼接。
- 区分地址协议。HTTPS 访问、SSH 访问可能使用不同的代理和认证;父仓库能下载不能证明子仓库也有权限。先按报错处理解析、超时、证书或账号授权,不修改整个系统的网络设置。
- 若维护者确认上游已经改过子模块 URL,且本机仍保留旧地址,先私下记录原配置和自己的镜像覆写,再选择是否同步。项目有意使用本地镜像时,不要盲目覆盖它。
git submodule sync --recursive
git submodule update --init --recursive --checkoutsync 只处理已经有本地 URL 配置的子模块,并可递归同步嵌套项。如果只想改一个模块,可同样追加“-- 实际路径”。若报错指出所需提交不存在,先让维护者核实父仓库引用是否已正确推送;不要随手切换到子仓库最新分支再假称已经还原项目。
验收:提交对齐和实际文件都要检查
git submodule status --recursive
git status --short --ignore-submodules=none- 确认所需子模块不再带未初始化、提交不匹配或冲突标志;如果项目刻意限制 active 子模块,还需核对实际需要的路径是否被包含。
- 打开之前缺失的目录,确认项目说明要求的源码存在。提交对齐不意味着额外依赖、LFS 文件或生成文件自动齐全。
- 确认没有意外修改 .gitmodules 或父仓库记录的子模块提交,再按项目提供的验证方式检查;不要把随意执行未知构建脚本作为联网测试。
失败后的恢复与求助
更新中断不会自动撤销所有已经成功的下载或检出。先保留现场;如果本次 sync 覆盖了刻意设置的镜像,按之前记录恢复相应本地地址。若此前有需要保留的分支或提交,应在确认工作区安全后按记录回到它,不执行 --force、reset --hard 或删除 .git/modules 来碰运气。
求助时提供 Git 版本、主仓库提交、失败子模块路径、地址协议和脱敏报错,并说明是否有自定义镜像或嵌套子模块。私有仓库 URL、用户名、访问令牌不要原样发送。单纯的 HTTPS/SSH 通路问题,可继续阅读下方终端代理教程。