How to checkout old git commit including all submodules recursively?

a 夏天 提交于 2021-02-05 19:54:31

问题


I have a git repo with multiple submodules. One of those submodules has multiple submodules of it's own. All I'm looking to do is check out an old commit on the master repo and have it checkout the appropriate commits from all submodules to get the correct state of the code at that time.

I know that git contains the information necessary as the ls-tree command can tell me which commit each submodule was on. However, I have to manually check out each one, which is painfully time consuming.

I'm looking for something like git checkout --recursive but such a command doesn't seem to exist.

Is there anyway to do this?


回答1:


You need two commands to achieve this:

git checkout *oldcommit*
git submodule update --recursive

Update: This answer is outdated as of 2018 – see VonC's answer below for more current information.




回答2:


Note: if you have multiple submodules (and submodules inside submodules), Git 2.14 (Q3 2017) will help (more recent that the OP from 2013)

git checkout --recurse-submodules

Using --recurse-submodules will update the content of all initialized submodules according to the commit recorded in the superproject.
If local modifications in a submodule would be overwritten the checkout will fail unless -f is used.

"git checkout --recurse-submodules" did not quite work with a submodule that itself has submodules. It will with Git 2.14.


Note: with Git 2.19 (Q3 2018), git checkout --recurse-submodules another-branch is more robust.
Before, it did not report in which submodule it failed to update the working tree, which resulted in an unhelpful error message.

See commit ba95d4e (20 Jun 2018) by Stefan Beller (stefanbeller).
(Merged by Junio C Hamano -- gitster -- in commit 392b3dd, 24 Jul 2018)

submodule.c: report the submodule that an error occurs in

When an error occurs in updating the working tree of a submodule in submodule_move_head, tell the user which submodule the error occurred in.

The call to read-tree contains a super-prefix, such that the read-tree will correctly report any path related issues, but some error messages do not contain a path, for example:

~/gerrit$ git checkout --recurse-submodules origin/master
~/gerrit$ fatal: failed to unpack tree object 07672f31880ba80300b38492df9d0acfcd6ee00a

Give the hint which submodule has a problem.




回答3:


Depending on whether or not there are more submodules in the old checkout, you might have to do the following to initialize submodules that are not there any more in new commits:

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


来源:https://stackoverflow.com/questions/15124430/how-to-checkout-old-git-commit-including-all-submodules-recursively

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!