如何递归地签出包含所有子模块的旧git提交?

如何递归地签出包含所有子模块的旧git提交?,git,git-submodules,Git,Git Submodules,我有一个带有多个子模块的git repo。其中一个子模块有自己的多个子模块。我所要做的就是在主repo上签出一个旧的提交,并让它签出所有子模块的适当提交,以获得代码当时的正确状态 我知道git包含了必要的信息,因为ls-tree命令可以告诉我每个子模块的提交时间。但是,我必须手动检查每一个,这非常耗时 我正在寻找类似于git checkout的东西——递归的,但这样的命令似乎不存在 是否仍要执行此操作?您需要两个命令来实现此操作: git checkout *oldcommit* git sub

我有一个带有多个子模块的git repo。其中一个子模块有自己的多个子模块。我所要做的就是在主repo上签出一个旧的提交,并让它签出所有子模块的适当提交,以获得代码当时的正确状态

我知道git包含了必要的信息,因为
ls-tree
命令可以告诉我每个子模块的提交时间。但是,我必须手动检查每一个,这非常耗时

我正在寻找类似于
git checkout的东西——递归的
,但这样的命令似乎不存在


是否仍要执行此操作?

您需要两个命令来实现此操作:

git checkout *oldcommit*
git submodule update --recursive


更新:此答案从2018年起已过时–有关更多最新信息,请参阅。

根据旧签出中是否有更多子模块,您可能必须执行以下操作来初始化新提交中不再存在的子模块:

git checkout *oldcommit*
git submodule init
git submodule update --recursive

注意:如果您有多个子模块(以及子模块中的子模块),Git 2.14(2017年第3季度)将有所帮助(比2013年的OP更新)

使用
--递归子模块
将根据超级项目中记录的提交更新所有初始化子模块的内容。
如果子模块中的本地修改将被覆盖,则签出将失败,除非使用
-f

git checkout--recurse子模块”
“与 自身具有子模块的子模块。它将使用Git2.14


注意:使用Git 2.19(2018年第3季度),
Git checkout——递归子模块另一个分支
更健壮。
以前,它没有报告更新工作树失败的子模块,这导致了一条没有帮助的错误消息

参见(2018年6月20日)作者。
(于2018年7月24日被合并)

子模块.c
:报告发生错误的子模块

更新中子模块的工作树时出错
submodule\u move\u head
,告诉用户错误发生在哪个子模块中

read tree
的调用包含一个超级前缀,使得
read tree
将正确报告任何与路径相关的问题,但会显示一些错误消息 不包含路径,例如:

~/gerrit$ git checkout --recurse-submodules origin/master
~/gerrit$ fatal: failed to unpack tree object 07672f31880ba80300b38492df9d0acfcd6ee00a
给出哪个子模块有问题的提示


非常感谢!当然,结果很简单。有谁能澄清一下
签出-递归子模块
子模块更新-递归
之间的区别吗?是否有一行代码与此等价?我发现von c的回答没有正确签出所有子模块,git状态显示修改。用你的,它确实正确地更新了整棵树。git v2.24.3注:
git checkout——递归子模块
现在实际存在(2017年)。但只有即将推出的Git2.14才能使它正常工作。看,我不明白为什么总是需要
-f
。没有
-f
它不会更新子模块。@linquize
-f
只有在子模块中有任何本地修改时才有必要。有人能澄清
签出-递归子模块
子模块更新-递归
之间的区别吗?@Lii sumodule update部分()将使用配置
子模块..更新
()
git checkout--recurse子模块
不会。@li另一个区别是:
checkout--recurse子模块
会更新您的父repo和子模块,而
submodule update--recurse
只会影响子模块的工作树,而不会更新父工作树。您救了我的命,先生!
~/gerrit$ git checkout --recurse-submodules origin/master
~/gerrit$ fatal: failed to unpack tree object 07672f31880ba80300b38492df9d0acfcd6ee00a