You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无远程变更时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:47:35