无远程变更时git submodule update与git pull的性能差异及疑问
Git子模块命令性能差异及相关疑问解答
在包含约30个扁平子模块的项目中,当远程仓库无变更(比如刚完成拉取/更新操作不久)时,git submodule update --remote --recursive --merge --jobs 8的执行速度远慢于git pull --recurse-submodule --jobs 8,具体耗时测试如下:
$ time git submodule update --remote --recursive --merge --jobs 8 real 0m47,996s $ time git pull --recurse-submodule --jobs 8 real 0m6,747s
通过设置GIT_TRACE=1 GIT_CURL_VERBOSE=1可以看到:git submodule update --remote --recursive --merge --jobs 8是按顺序检查每个子模块的远程变更,而git pull --recurse-submodule --jobs 8会并行检查所有子模块的远程状态(先检查主仓库)。这个现象在Git 2.25.1和2.42.0版本中都已验证。
疑问解答
1. 能不能让git submodule update --remote --merge --jobs 8并行检查远程状态?不行的话原因是什么?
目前Git原生做不到这一点,问题出在命令的设计逻辑上:
--jobs参数在git submodule update里,只作用于拉取子模块代码内容的阶段,而远程状态检查(确认每个子模块的远程分支是否有更新)的流程,当前实现是串行的,没有做并行处理。- 反观
git pull --recurse-submodules,它的并行逻辑是单独实现的:会先批量触发所有子模块的远程检查操作,再统一处理后续更新,和submodule update的执行流程完全是两套逻辑,所以能做到并行检查。
2. 如果不用管主仓库,git pull --recurse-submodule和git submodule update --remote --merge功能一样吗?是不是该优先用前者提升性能?
两者功能不完全等价,得看具体场景:
- 核心差异:
git pull --recurse-submodules会先执行主仓库的git pull(哪怕主仓库没变更,这个操作本身耗时极短),再处理子模块;而git submodule update --remote --merge只操作子模块,不会碰主仓库。 - 要是确实不能动主仓库,别用
git pull --recurse-submodules,可以用组合命令替代:先执行git submodule foreach --jobs 8 git fetch(并行拉取所有子模块的远程信息),再执行git submodule update --merge,这样既跳过主仓库操作,又能利用并行提升速度。 - 要是能接受主仓库跑一遍
pull,那git pull --recurse-submodules --jobs 8确实能更快完成子模块的远程检查,性能优势明显。
3. 当有远程变更时,不同场景下的处理逻辑是什么?
子模块处于主分支且无本地提交
- 执行
git submodule update --remote --merge:会把子模块远程主分支的最新提交合并到本地主分支(因为无本地提交,实际是快进操作),最终子模块的HEAD指向远程最新提交。 - 执行
git pull --recurse-submodules:先拉取主仓库(有变更的话),然后子模块会执行git pull,同样是快进合并远程主分支的最新提交到本地。
子模块处于featureXYZ分支时
- 远程主分支推进:
git submodule update --remote:默认会拉取子模块配置的跟踪分支(一般是主分支)的最新提交,然后尝试合并到当前的featureXYZ分支。如果两者无冲突,会自动完成合并;有冲突的话会触发合并冲突,需要手动解决。git pull --recurse-submodules:只会在子模块里执行git pull,也就是拉取当前featureXYZ分支的远程变更,不会处理远程主分支的更新。
- 远程featureXYZ分支推进:
git submodule update --remote:默认不会拉取远程featureXYZ分支的变更,除非你在.gitmodules里把该子模块的跟踪分支改成了featureXYZ;否则它只会拉取配置的默认分支(比如主分支)。git pull --recurse-submodules:会在子模块中执行git pull,拉取远程featureXYZ分支的最新提交,快进合并到本地(无本地提交的情况下)。
内容的提问来源于stack exchange,提问作者jonenst
相关产品推荐
相关产品推荐

