git submodule update --depth 1为何拉取远程HEAD?如何仅拉取指定提交?
Git子模块
update --depth 1为何会下载2个提交? 这是某Git相关问题的间接续篇。我尝试克隆包含ARM-software/CMSIS_5作为子模块的raspberrypi/debugprobe仓库,目标是仅下载超项目引用的子模块提交,无额外开销。但执行相关操作后,每个子模块会下载2个提交(远程HEAD提交+指定提交),而非预期的1个。
操作步骤及日志
git clone https://github.com/raspberrypi/debugprobe.git cd debugprobe/ GIT_LFS_SKIP_SMUDGE=1 git submodule update --init --depth 1 cd CMSIS_5/ git log --all --graph --oneline cd ../freertos/ git log --all --graph --oneline cd ..
CMSIS_5日志输出:
* c12fabc (grafted, origin/develop, origin/HEAD, develop) Update README.md (#1669) * a65b7c9 (grafted, HEAD) Bump version and docs for release.
freertos日志输出:
* 5588ae6 (grafted, origin/main, origin/HEAD, main) Update ARM_CRx_No_GIC port (#1101) * 2dfdfc4 (grafted, HEAD) Add Cortex M7 r0p1 Errata 837070 workaround to CM4_MPU ports (#513)
问题
- 此行为是否为
git submodule update --depth 1的预期表现? - 能否用单个submodule命令避免下载远程HEAD?
现有临时解决方法
需手动初始化每个子模块并拉取指定提交:
git clone https://github.com/raspberrypi/debugprobe.git cd debugprobe/ git submodule init git submodule status --cached cd CMSIS_5/ git init GIT_LFS_SKIP_SMUDGE=1 git pull --depth 1 https://github.com/ARM-software/CMSIS_5.git a65b7c9a3e6502127fdb80eb288d8cbdf251a6f4 git log --all --graph --oneline cd ../freertos/ git init git pull --depth 1 https://github.com/FreeRTOS/FreeRTOS-Kernel.git 2dfdfc4ba4d8bb487c8ea6b5428d7d742ce162b8 git log --all --graph --oneline cd ..
执行后子模块仅保留指定提交:
CMSIS_5日志:
* a65b7c9 (grafted, HEAD -> main) Bump version and docs for release.
freertos日志:
* 2dfdfc4 (grafted, HEAD -> main) Add Cortex M7 r0p1 Errata 837070 workaround to CM4_MPU ports (#513)
解答
行为原因
这是Git子模块的预期行为。当执行git submodule update --init --depth 1时,Git会先对子模块的远程默认分支进行浅克隆(仅拉取该分支的最新提交,即远程HEAD),随后再切换到超项目所引用的特定提交。因此本地仓库会同时存在这两个提交——Git需要先建立远程分支的引用,才能完成目标提交的checkout操作。
简洁解决方案
无需手动逐个处理子模块,可使用以下两种方式实现目标:
方式1:克隆时直接拉取子模块
GIT_LFS_SKIP_SMUDGE=1 git clone --recurse-submodules --shallow-submodules https://github.com/raspberrypi/debugprobe.git
--shallow-submodules参数会让每个子模块仅克隆超项目引用的提交,不会额外拉取远程HEAD。
方式2:克隆超项目后更新子模块
git clone https://github.com/raspberrypi/debugprobe.git cd debugprobe/ git submodule init GIT_LFS_SKIP_SMUDGE=1 git submodule update --depth 1 --no-fetch
--no-fetch参数会阻止Git从远程子模块仓库拉取额外分支引用,仅基于已有的缓存信息完成目标提交的浅克隆。
内容的提问来源于stack exchange,提问作者recursivenomad
相关产品推荐
相关产品推荐

