如何移除 Git 子模块(submodule)
先保全子模块本地工作,再 git submodule deinit -- <路径>、git rm <路径>,检查 .gitmodules 后提交。内部 Git 存储可保留以便历史检出,清理前须核实真实位置和备份。
先确认子模块内没有未提交或未推送的工作,并备份必要内容。 以下步骤移除当前版本中的子模块;清理内部 Git 存储是可选的,保留它有利于检出历史版本。
git submodule deinit -- vendor/lib # 1. 反初始化(清 .git/config 注册)
git rm vendor/lib # 2. 从索引和工作区删除(含 .gitmodules 条目)
# 可选:确认不需要子模块中的本地历史后,再清理其内部存储
git commit -m "移除 vendor/lib 子模块" # 4. 提交
验证清理干净
cat .gitmodules # 应不再有该子模块条目;空文件可自行决定是否删除
git config --list | grep submodule # 无该子模块配置
git status # 干净
只删目录会留下什么
.gitmodules里的条目 → 别人 clone 时报错;.git/config里的注册信息;- 内部 Git 存储通常位于 .git/modules 下,但模块名未必等于路径;用 git rev-parse --git-dir 核对,保留该存储不是残留错误,有助于历史检出。
移除后想恢复
git submodule add <仓库地址> vendor/lib # 重新添加
历史里也有记录:git log -- .gitmodules 能翻到曾经的子模块配置。
常见问题(FAQ)
Q:git rm 报 "not removing recursively"?
先检查 git ls-files --stage -- vendor/lib,真正的子模块条目模式为 160000;该错误可能表示它其实是普通跟踪目录,需要按实际类型处理,不能用 -f 当通用修复。
Q:能把子模块"转正"为普通目录吗?
可以:先把需要保留的工作区内容备份到仓库外(不复制内部 .git 指针),再按上面移除,最后从备份把代码复制进来 git add 提交(历史不带过来;要历史用 git subtree 合并)。
Q:.gitmodules 空了要提交删除吗?
git rm 会自动处理 .gitmodules 条目的移除并暂存;如果文件已空且不再需要,可显式删除并提交。