git pull --recurse-submodules执行后子模块未更新问题排查
问题根因
你的操作有两处核心错误,本质是对Git子模块的存储逻辑和对应命令的默认行为存在认知偏差:
- 初始添加子模块的命令顺序完全颠倒。你在执行
git add -A、git commit之前就运行了git push --recurse-submodules=on-demand,这时候主仓库根本没暂存任何子模块相关的变更(包括.gitmodules配置文件、子模块目录的提交指针),这个push属于无效空跑,没有任何实际作用。正确的初始流程应该是先完成子模块添加、配置、暂存、本地提交,最后再执行推送。 - 对子模块的同步逻辑理解有误:
- 主仓库本身不会自动跟踪子模块远端分支的最新提交,它只会固定记录提交时子模块所在的具体提交哈希。你只配置了
submodule.dss.update=merge,但没有给子模块设置要跟踪的远端分支,子模块默认不会主动拉取远端master的最新提交合并到本地。 git pull --recurse-submodules默认只会把远端子模块的提交对象拉到本地存储,不会自动触发子模块工作区的更新。你看到日志里输出3999c9c..1362f93 master -> origin/master,只是说明子模块本地的远端追踪指针origin/master更新到了最新提交,但子模块实际工作区还停留在主仓库记录的旧提交3999c9c上,没有自动切换或合并到最新版本。
- 主仓库本身不会自动跟踪子模块远端分支的最新提交,它只会固定记录提交时子模块所在的具体提交哈希。你只配置了
修复方法
要正常同步子模块最新版本,按以下步骤操作即可:
- 先给子模块配置需要跟踪的远端分支:
git config -f .gitmodules submodule.dss.branch master - 执行带递归更新参数的拉取命令,让子模块自动合并远端跟踪分支的最新提交:
git pull --recurse-submodules --recurse-submodules=on-demand
如果只是单次同步不需要修改长期配置,直接在主仓库目录下执行:git submodule update --remote --merge
执行完成后再运行git submodule status,就能看到子模块已经指向最新的1362f93提交。这时候记得把主仓库里更新后的子模块指针提交、推送到远端,其他协作者拉取主仓库代码时就能同步到对应的子模块版本。
补充说明:子模块的核心设计逻辑就是「主仓库锁定子模块的确定提交版本」,保证所有协作者使用的子模块代码完全一致。如果需要长期跟随子模块某个分支的最新提交,必须配置
submodule.<子模块名>.branch参数,否则所有子模块更新都会以主仓库记录的提交哈希为准,不会自动拉取最新代码。
内容的提问来源于stack exchange,提问作者mooky
相关产品推荐
相关产品推荐

