科技 · 实用指南
Git 提示子模块路径没有 URL?先核对 gitlink 与 .gitmodules,再删除文件
分别检查失败提交、当前索引、版本化映射与本地检出,再选择修复、同步、deinit 或从仓库移除。

“No url found for submodule path” 首先要求核查路径到 URL 的映射,不应直接删除 Git 元数据。记录子模块提交的 gitlink 与 .gitmodules 中的配置是两份状态;当前索引、磁盘工作文件和真正失败的提交可能并不一致。
先保留错误原文、主仓库失败提交、路径和本地工作,再证明已提交的 gitlink 与映射、检查本地配置,最后按仓库真实意图处理。下文的 Git 2.51.1 隔离实验说明:磁盘文件正确,不代表失败提交已经修好。
分别证明失败提交与当前索引
保存完整错误,核实失败检出或 CI 实际使用的主仓库提交。在主仓库根目录操作,写入前先保留未提交工作。用 git ls-files --stage -- path/to/item 查看当前索引;模式 160000 表明它是 gitlink,并给出对象 ID。仅看到嵌套 .git 目录,不能据此认定子模块。
再执行 git ls-tree --full-tree COMMIT -- path/to/item,把 COMMIT 换成已核实的失败提交 ID。它读取指定提交树,而不是假设当前索引仍与其一致。若那里没有 gitlink,先调查是否是另一份检出、嵌套主仓库、暂存变更或错误路径,再决定是否修复映射。
从同一提交读取映射
用 git show COMMIT:.gitmodules 查看失败提交中的版本化文件。文件不存在本身就是证据,不能悄悄拿另一分支的文件代替。寻找 path 与 gitlink 精确匹配的配置节,包括大小写。Git 要求路径唯一、相对根目录且没有末尾斜杠,并具有 URL;配置节名称不必等于路径。
检查当前工作区文件可用兼容写法 git config -f .gitmodules --get-regexp '^submodule\..*\.(path|url)$'。正则表达式必须加引号,避免 shell 把 | 当管道。将结果与提交中的文件对比;只在磁盘恢复一份未提交文件,不会改变干净检出失败提交时得到的内容。
单独检查本地配置,只同步预期 URL
用 git config --local --get-regexp '^submodule\..*\.(url|active)$' 单独查看已初始化的本地设置。键对应子模块名称,需要与 .gitmodules 中的 path 关联。初始化可从版本化模板填入本地配置,此后的本地覆盖值可能不同。已 deinit 的子模块仍可能有仓库定义,却没有检出文件。
仓库有意更改现有 URL 时,先核实获准远程地址,修正或更新 .gitmodules,再对目标已初始化子模块执行 git submodule sync --recursive -- path/to/item,更新前检查生效 URL。sync 只同步已登记的 URL 配置,不能补缺失映射、改变记录的子提交或解决私有远程授权。
区分保留、本地移除与仓库移除
要保留子模块,就恢复精确路径与获准 URL,暂存映射、检查差异,再创建预期的修复提交。随后初始化或更新,并对这个修复提交做干净检出验证。若只想更改 URL,应保留 gitlink,除非确实也要更新子提交,同时同步受影响的已初始化检出。
只想去掉本地检出时,先保护本地工作,再用 git submodule deinit -- path/to/item;不要加 --force 丢弃修改。若要从版本控制中移除,用 git rm -- path/to/item,并在提交前审查 gitlink 删除和 .gitmodules 节变更。两者目标不同;git rm --cached 只操作索引,不会像普通 git rm 那样自动清理映射节。
先用干净克隆验证,再怀疑缓存
在隔离的 Git 2.51.1 实验仓库中,我们提交了缺少映射的 gitlink,新的本地克隆复现完全相同的 fatal 错误。索引与提交树都显示 160000。只把 .gitmodules 放回磁盘后,工作文件检查成功,但读取失败提交的 git show 仍失败。提交恢复的映射后,干净本地克隆初始化成功;随后 deinit 清除了本地检出状态,而已提交 gitlink 与映射保持不变。
实验只用本地子仓库,仅对各条实验命令放行 file 传输,没有复现你的 CI、网络或私有授权;该放行不是生产修复方案。只有已提交元数据正确后,才调查可丢弃检出是否陈旧。先保留日志与工作,适当时只重建可丢弃检出,并记录失败和修复提交及干净克隆结果。不要从删除 .git/modules、嵌套 .git 数据或开发者工作目录开始。
