如果您在 Mac 上克隆了一个 Git 仓库,且其子模块文件夹为空,请打开“终端”,进入该仓库,然后运行 git submodule update --init --recursive。这将初始化项目中记录的子模块,检出父仓库指定的提交,并同时处理嵌套子模块。您需要安装 Git 并拥有访问各个子模块远程仓库的权限。

在克隆的仓库中运行初始化命令

打开“终端”,使用 cd 进入通过 git clone 创建的目录。如果目录名包含空格,请将其用引号引起来,例如:

cd "$HOME/Projects/My Project"
git submodule update --init --recursive

将示例路径替换为您克隆仓库的实际位置。您也可以输入 cd ,然后从访达(Finder)中将仓库文件夹拖入“终端”窗口以插入其路径,最后按 Return 键。Apple 官方文档指出“终端”是 macOS 的命令行界面,并将 zsh 标识为其默认 shell;上述命令使用的是可在 zsh 中运行的常规 shell 语法。在 Mac 上打开或退出“终端”,在 Mac 上的“终端”中更改默认 Shell

Git 官方文档说明,--init 用于初始化尚未初始化的子模块,而 --recursive 还会递归更新嵌套的子模块。update 会拉取缺失的提交并检出父仓库所期望的版本。git-submodule 文档

检查子模块是否已初始化

要查看父仓库记录的内容,请运行:

git submodule status --recursive

子模块状态行通常会显示提交 ID 和路径。开头的减号(-)表示该子模块未初始化;加号(+)表示其当前检出的提交与父仓库记录的提交不同;U 则表示存在冲突。递归状态选项也会报告嵌套子模块的状态。git-submodule 文档

如果输出列出了带有减号的路径,请从仓库的顶层目录再次运行初始化命令。如果未出现任何子模块,请检查当前克隆中是否确实包含 .gitmodules 文件,以及您是否处于目标仓库中。仓库可能本身没有子模块,或者您克隆的提交未记录任何子模块。

了解检出的具体版本

子模块本身是一个独立的 Git 仓库,而父仓库记录了它特定的某个提交。常规的 update 行为会检出该记录的提交,通常使子模块处于“分离头指针”(detached HEAD)状态。这在您设置父项目时是符合预期的:它会重现父项目所选择的版本。Git - 子模块,git-submodule 文档

因此,当您的目标只是初始化克隆时,请不要添加 --remote。该选项会使用子模块的远程跟踪分支,而不是父仓库记录的提交,这可能会导致版本不一致。如果您打算在子模块内部进行开发,请先了解该项目的工作流程;切换分支或在子模块内部提交代码与初始化是两码事。

如果命令执行失败

子模块更新需要连接项目配置中列出的远程仓库,因此网络故障或缺失访问权限可能会阻止检出。私有子模块可能需要您向托管服务进行身份验证或拥有该仓库的权限。如果 Git 报告找不到仓库或无法解析主机,请确认您的网络连接和访问权限,然后重试。

如果项目最近更改了子模块的 URL,使用 git submodule sync --recursive 可以从 .gitmodules 同步本地 URL 配置;随后请再运行 git submodule update --init --recursive。Git 文档说明 sync 用于为已初始化或新添加的子模块更新 URL 配置。git-submodule 文档

如果您在子模块内已经有本地未提交的修改,请在强制更新或切换版本之前检查这些工作。标准的初始化命令不会要求 Git 强行覆盖本地修改进行检出;请妥善解决或保留这些工作,而不是将删除目录作为排查问题的捷径。

一旦 git submodule status --recursive 显示预期的提交 ID 且开头没有减号,即表示仓库记录的子模块版本已全部检出。除非项目说明要求在子模块内单独开展工作,否则请继续在父仓库中进行操作。

来源