Git子模块报错:无法锁定config文件无对应目录解决方案
问题原因
这个报错完全是新旧版本Git的子模块实现逻辑差异导致的:Git 1.7.8之前的版本,子模块的.git元数据目录是直接放在子模块自己的文件夹里的,不会统一存到主仓库的.git/modules路径下。你现在用新版本Git跑submodule相关命令时,程序默认会去.git/modules下找对应子模块的配置文件,路径不存在自然就报找不到config、没法锁文件的错,和操作本身没有关系。
解决方法
你可以根据自己是否需要保留子模块本地修改,选以下两种方案之一处理。
方案一:手动迁移,保留子模块本地修改
如果现有子模块里有你改过的未提交内容不想丢,按以下步骤逐个处理子模块即可:
- 先创建新版本Git预期的modules目录结构
mkdir -p .git/modules/vim/bundle
- 对
.gitmodules里列的每个剩余子模块,依次执行以下操作(以tlib_vim为例,处理其他子模块时替换成对应路径就行):- 如果之前执行deinit已经清空了子模块目录,先从当前提交把目录恢复回来:
git checkout HEAD -- vim/bundle/tlib_vim- 把子模块目录里旧的.git元数据文件夹,移动到新版本Git要求的存放路径:
mv vim/bundle/tlib_vim/.git .git/modules/vim/bundle/tlib_vim- 在子模块目录下创建gitdir指向文件,关联到移动后的元数据路径:
echo "gitdir: ../../../.git/modules/vim/bundle/tlib_vim" > vim/bundle/tlib_vim/.git- 补全子模块的worktree配置,补上之前deinit操作没设置成功的参数:
git config -f .git/modules/vim/bundle/tlib_vim/config core.worktree "../../../../vim/bundle/tlib_vim" - 所有子模块都迁移完之后,执行同步命令刷新Git的子模块配置缓存:
git submodule sync --recursive
- 这时候再跑deinit、update之类的子模块命令就不会报错了,要更新剩余子模块直接执行:
git submodule update --init --remote --merge
方案二:全量重置,操作更快捷
如果子模块里没有需要保留的本地修改,直接重置所有子模块就行,不用逐个迁移:
# 删除本地所有子模块目录 rm -rf vim/bundle/* # 清除暂存区的子模块缓存 git rm --cached -r vim/bundle # 按照.gitmodules配置重新拉取所有子模块,Git会自动创建符合新版本规则的元数据结构 git submodule update --init --recursive
注意:执行删除操作前确认子模块内没有需要留存的未提交修改,避免数据丢失。
内容的提问来源于stack exchange,提问作者todd_dsm
相关产品推荐
相关产品推荐

