子模块不会自动跟随父仓库分支切换版本,仅忠于父仓库当前commit记录的精确hash;切换分支后需执行git submodule update --init --recursive检出该分支所记录的对应子模块提交。

子模块怎么跟着父仓库分支自动切换版本
子模块不会自动跟随父仓库分支变化而切换代码——它只忠于父仓库当前 commit 记录的精确 commit hash。所谓“联动”,本质是父仓库不同分支各自记录了不同子模块 commit,切换分支时 git submodule update --init --recursive 才会检出对应版本。
- 父仓库的每个分支可以指向子模块的不同 commit;
git checkout feature/login后,子模块内容是否变,取决于该分支的 HEAD 是否记录了新 hash - 如果
feature/login分支在创建时没更新子模块指针,它仍沿用main分支记录的老 hash,git submodule update不会拉新代码 - 想让子模块“看起来联动”,必须在切分支后手动提交子模块新指针:进子模块目录改完 push,再回父仓
git add path/to/submodule并 commit
为什么 git submodule update 没更新到远程最新代码
因为 git submodule update 默认只做一件事:检出父仓库当前 commit 锁定的那个 commit hash,不 fetch、不 pull、不关心远程有没有新提交。
通用Git项目监控工具,支持GitHub、GitLab、Gitee等平台。可增删仓库、检查更新、自动拉取代码并生成变更摘要。用于“监控项目”“检查更新”“添加仓库”等场景。
- 常见现象:子模块目录里
git log看不到上游新 commit,git status显示 “clean”,但其实落后好几版 - 要拉远程最新,得用
git submodule update --remote --recursive,它会先fetch再按.gitmodules里branch = main的配置检出最新 commit - 如果
.gitmodules没配branch,它会 fallback 到远程仓库的 HEAD 分支(可能已变更,不可靠)
git submodule update --remote 和 --checkout/--merge 的区别
三者行为差异直接影响本地修改是否保留、冲突如何处理,不是可有可无的开关。
-
--checkout(默认):强制重置子模块工作区到远程最新 commit,丢弃所有本地未提交改动 -
--merge:执行git merge origin/main,保留本地修改,但可能产生冲突需手动解决 -
--rebase:对本地未推送提交做变基,适合你正在子模块里开发功能且想保持线性历史 - CI 构建建议加
--force --checkout,避免因缓存或残留导致构建不一致
子模块 URL 或分支改了,怎么安全同步到所有协作者
URL 或 branch 变更属于元信息变更,必须显式提交,否则别人 git clone 后仍用旧配置。
- 改完
.gitmodules后,运行git add .gitmodules+git commit,这是关键一步 - 接着执行
git submodule sync --recursive,把新 URL/branch 写进每个子模块的.git/config - 最后
git submodule update --init --recursive,确保本地子模块按新配置初始化 - 注意:
git submodule sync不会拉代码,只是同步配置;漏掉这步,首次克隆者会卡在旧 URL 上报错

















