Git 递归更新子模块

回答 7 浏览 54.6万 2012-04-16

我的项目结构

ProjectA
-FrameworkA (submodule)
--Twig (submodule of FrameworkA)

如何递归更新子模块?我已经尝试过一些 git 命令(在 ProjectA root 上)

git submodule foreach git pull origin master

或者

git submodule foreach --recursive git pull origin master

但无法拉取 Twig 的文件。

complez 提问于2012-04-16
git-deep 怎么样?Mathew Kurian 2017-01-02
7 个回答
#1楼 已采纳
得票数 896
git submodule update --recursive

您可能还想使用 --init 选项,这将使其初始化任何未初始化的子模块:

git submodule update --init --recursive

注意:在某些旧版本的 Git 中,如果使用 --init 选项,则可能不会更新已初始化的子模块。在这种情况下,您还应该运行不带 --init 选项的命令。

drewag 提问于2012-04-16
drewag 修改于2019-07-17
递归添加子模块怎么样? “git submodule add FrameworkA.git”只是拉取FrameworkA的文件。complez 2012-04-16
您可以只执行“git submodule add blah”,然后执行“git submodule update --init --recursive”。drewag 2012-04-16
这和我下面的方式有什么不同吗?William Entriken 2013-09-26
@Irineau 关于如果使用 --init 则已初始化的子模块不会更新的注释与我在 Git 2.2.2 上的经验不符。当我使用 git submodule update --init --recursive 时,我看到已经初始化的顶级子模块和嵌套子模块都已检查出正确的提交,并且我认为需要使用和不使用 --init 运行命令的说法是完全错误的。除非有人能够证明这是这种行为的证据,或者证明它在版本之间发生了变化并且曾经是正确的,否则我计划将其完全编辑掉。Mark Amery 2015-02-24
@MarkAmery,我记得这是某个我不记得的 git 版本中的问题。我刚刚在1.9.3中测试过,这个问题似乎不再存在了。我更新了答案以引用模糊的“旧版本”。如果任何人都可以指定哪个版本改变了此行为,那就太好了。drewag 2015-02-24
#2楼
得票数 57

我使用的方式是:

git submodule update --init --recursive
git submodule foreach --recursive git fetch
git submodule foreach git merge origin master
William Entriken 提问于2013-09-26
我将最后一行更改为:git submodule foreach git pull --ff-only origin masterGilad Peleg 2014-10-23
我还会在最后一行添加 --recursive:“git submodule foreach --recursive git merge origin master”,否则当它本身更新了子模块时,您可能会得到一个脏子模块。Michael Scott Asato Cuthbert 2015-10-02
过去三个小时一直在寻找这个。谢谢你,先生。除此之外,您还可以使用这些命令进行提交,例如:git submodule foreach --recursive 'git commit -a | :': 使其循环,无论结果如何。请参阅stackoverflow.com/questions/19728933/…Fledgling Pidgeon 2017-05-23
#3楼
得票数 25

由于子模块的默认分支可能不是master(在我的情况下经常发生),这就是我自动执行完整 Git 子模块升级的方式:

git submodule init
git submodule update
git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'
Sebastien Varrette 提问于2013-12-03
我尝试在我的 通用 Makefile 中添加此命令,但我仍然坚持让 GNU Make 忽略 $(...) 序列的解释,尽管它存在于简单的引号中。有人有主意吗?Sebastien Varrette 2014-03-19
你的命令正是我所需要的,谢谢!但我得到:Entering 'Core' fatal: ambiguous argument 'origin/HEAD': unknown revision or path not in the working tree. 其中Core 是子模块Sanandrea 2017-05-03
另外,我想你需要弄清楚这个评论 stackoverflow.com/a/18008139/3383543Ahmad AlMughrabi 2017-07-04
没有递归选项意味着只有当您的子模块不再包含子模块时才有效。erikbstack 2017-11-12
这个答案需要给新手一个警告:reset --hardclean -dfxPLG 2022-12-29
#4楼
得票数 24

在最近的 Git(我使用的是 v2.15.1)中,以下代码将以递归方式将上游子模块更改合并到子模块中:

git submodule update --recursive --remote --merge

您可以添加 --init 来初始化任何未初始化的子模块,如果您想变基而不是合并,则可以使用 --rebase

您需要随后提交更改:

git add . && git commit -m 'Update submodules to latest revisions'
mrts 提问于2018-01-22
mrts 修改于2018-01-22
这个,我以为我做错了什么,但你的回答向我证实了 git submodule update --remote my-dir/my-submodule 也同样有效iomv 2020-02-18
#5楼
得票数 10

怎么样

git config --global submodule.recurse true

忘记它了吗?

请参阅git 文档

Stefano Favero 提问于2022-07-18
Martin Thoma 修改于2023-07-19
#6楼
得票数 1

您可以将以下内容添加到您的Makefile

submodule:
    git submodule update --init --recursive
    git submodule foreach 'git fetch origin; git checkout $$(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'

然后你可以在每次想要更新子模块时简单地运行make submodule

Shubham Chaudhary 提问于2022-03-09
#7楼
得票数 0

我有一个子模块导致了问题(上面 Sanandrea 报告的“致命:...”)。导航到子模块并使用“git clean -dfx”解决了它。

Duane Rosengartner 提问于2022-03-25
Duane Rosengartner 修改于2022-04-15
如果您要添加新信息,您可以在完全解决问题后完成答案吗? “尝试使用相同的”让我不确定这是一个答案还是只是一个评论。joanis 2022-03-25