如何仅递归更新已设置为跟踪分支的Git子模块?
问题描述
- 我的
.gitmodules文件里定义了多个子模块,其中一部分配置了跟踪分支,剩下的没设置跟踪分支。 - 我想用一条命令只更新那些配置了跟踪分支的子模块,没跟踪分支的子模块就保持当前提交版本,别更到远程最新HEAD。
- 常规的递归子模块更新命令会把所有子模块都更了,不符合我的需求:
git submodule update --recursive --remote --checkout - 之前试过在
.gitmodules的子模块branch字段填标签,但标签不被识别成有效引用(SHA值也不行,这倒是符合预期),执行上面的命令时会报错:$ git submodule update --recursive --remote --checkout fatal: Unable to find refs/remotes/origin/tags/<tag> revision in submodule path <path>
解决方案
方法1:过滤跟踪分支的子模块来更新
用git submodule foreach加条件判断,只给配置了branch字段的子模块做远程更新:
git submodule foreach 'git config -f $toplevel/.gitmodules submodule.$name.branch && git pull origin $(git config -f $toplevel/.gitmodules submodule.$name.branch)'
要是需要处理嵌套的子模块,加上--recursive参数就行:
git submodule foreach --recursive 'git config -f $toplevel/.gitmodules submodule.$name.branch && git pull origin $(git config -f $toplevel/.gitmodules submodule.$name.branch)'
原理就是先检查当前子模块有没有在.gitmodules里配置branch,有就拉对应分支的最新代码。
方法2:固定不需要跟踪分支的子模块版本
如果有些子模块就是要固定在某个标签或SHA版本,别在branch字段填这些,直接这么操作:
- 进入子模块目录,切换到目标标签或SHA:
cd path/to/submodule git checkout tags/<tag> # 或者 git checkout <SHA> cd ../.. git add path/to/submodule git commit -m "把子模块<name>固定到<tag/SHA>版本" - 之后要是想更新跟踪分支的子模块,同时保持固定版本的子模块不动,可以用这条组合命令:
它会先让所有子模块回到仓库记录的版本,再更新那些跟踪分支的子模块到最新。git submodule update --recursive --checkout; git submodule foreach 'git config -f $toplevel/.gitmodules submodule.$name.branch && git pull origin $(git config -f $toplevel/.gitmodules submodule.$name.branch)'
注意点
.gitmodules里的branch字段只认分支名,不支持标签或SHA值。因为--remote参数是要拉远程对应分支的最新提交,标签和SHA都是固定的版本引用,没法用来跟踪更新,所以填了肯定会报错。
内容的提问来源于stack exchange,提问作者esando
相关产品推荐
相关产品推荐

