为什么`git checkout` 不自动执行`git submodule update --recursive`?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22328053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why doesn't `git checkout` automatically do `git submodule update --recursive`?
提问by Markus
Someone please help me understand submodules in git. I know they are getting a lot of bashing around the internet but since I assume the git developers are smart people there must a reason for the current behavior - and maybe a way to work around my problem.
有人请帮助我理解 git 中的子模块。我知道他们在互联网上受到了很多抨击,但既然我认为 git 开发人员是聪明人,那么当前的行为肯定有原因——也许是一种解决我的问题的方法。
So, I have a project and some submodules. The project have different branches, like:
所以,我有一个项目和一些子模块。该项目有不同的分支,例如:
- MyApp_version2
- MyApp_version3
- MyApp_version4
- MyApp_liteversion
- MyApp_development
- MyApp_version2
- MyApp_version3
- MyApp_version4
- MyApp_liteversion
- MyApp_development
My submodules doesn't update that often (maybe once a week) so I'm fine with them not being attached to the head of the submodule repository automatically.
我的子模块不经常更新(可能每周一次)所以我很好,它们不会自动附加到子模块存储库的头部。
However, when I check out an old branch - because I need to fix a bug in an old version of the software - I also need to update the submodules.
但是,当我检出旧分支时——因为我需要修复旧版本软件中的错误——我还需要更新子模块。
Why do I need to do this?
为什么我需要这样做?
I would expect git to work like svn. When I commit my work in my main repo I would expect git to think something along these lines: "OK, he wants to commit his work now. I can see the submodules are currently at revision abc so when he at some point in the future get's back to this commit he probably wants the submodules at the same revision again."
我希望 git 像 svn 一样工作。当我在我的主仓库中提交我的工作时,我希望 git 会按照以下思路思考:“好吧,他现在想提交他的工作。我可以看到子模块目前正在修订 abc,所以当他在未来的某个时候回到这个提交,他可能希望子模块再次处于同一修订版。”
I can not see a single case where you would want the submodules to stay at the current revision while you go back 3 years in your main repository. However, there must be a reason for this implementation, right?
我看不到任何一种情况,当您在主存储库中返回 3 年时,您希望子模块保持当前版本。不过,这种实现肯定是有原因的吧?
I would really like to hear if any of you know the thoughts behind this, but in any case I would really like a solution. Is there a way to tell git: "I want to commit this work with these submodules. If I at some point go back to this state I want the submodules to be checked out at the correct version as well."
我真的很想听听你们中是否有人知道这背后的想法,但无论如何,我真的很想要一个解决方案。有没有办法告诉 git:“我想用这些子模块提交这项工作。如果我在某个时候回到这个状态,我希望子模块也能以正确的版本检出。”
Example for clarification
说明示例
My main repository is an application which needs to use SSL, and I find a SSL library (libSSL) I add as a submodule.
我的主存储库是一个需要使用 SSL 的应用程序,我找到了一个 SSL 库 (libSSL) 作为子模块添加。
On Oct. 31 2010 I create a commit in my main repository (2fd4e1) while the submodule points to libSSL version 3 (c67a2d).
2010 年 10 月 31 日,我在主存储库 (2fd4e1) 中创建了一个提交,而子模块指向 libSSL 版本 3 (c67a2d)。
Time passes, libSSl gets updated to version 34, I adapt my code, life it good.
时间过去了,libSSl 更新到版本 34,我调整了我的代码,生活很好。
On May 14 2013 I create a new commit (28fced) and submodule points to the most recent version of libSSL (849ee1).
2013 年 5 月 14 日,我创建了一个新提交 (28fced),并且子模块指向最新版本的 libSSL (849ee1)。
However, if I check out 2fd4e1 my submodule will stay at 849ee1 even though the original commit was created with c67a2d. Git knows I made the original commit with c67a2d and I don't see how you could possibly want a another submodule than the one the original commit was created with.
但是,如果我检出 2fd4e1,即使原始提交是使用 c67a2d 创建的,我的子模块也会保持在 849ee1。Git 知道我使用 c67a2d 进行了原始提交,但我不知道您怎么可能想要另一个子模块而不是创建原始提交的子模块。
回答by Cyril Cressent
It sounds like what you want to do can be achieved from git v2.13 on with the new --recurse-submodules
option of git checkout
. From the git-checkout
manual page:
这听起来像你想做的事可以从混帐v2.13对新达到什么样--recurse-submodules
的选择git checkout
。从git-checkout
手册页:
--[no-]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. If nothing (or --no-recurse-submodules) is used, the work trees of submodules will not be updated.
--[no-]recurse-submodules
使用 --recurse-submodules 将根据超级项目中记录的提交更新所有已初始化子模块的内容。如果子模块中的本地修改将被覆盖,除非使用 -f,否则检出将失败。如果没有使用(或 --no-recurse-submodules),子模块的工作树将不会更新。
See also this relevant git mailing list message about that new option.
另请参阅有关该新选项的相关 git 邮件列表消息。
回答by thomas bogard
Simplify your shortcut/aliases by using :
使用以下命令简化您的快捷方式/别名:
alias checkitout='git checkout ; git submodule update --recursive'
回答by SzG
You basically want git to do all operations recursively and automatically for all submodules. Which is probably trivial in a centralized client-server model like svn.
您基本上希望 git 为所有子模块递归和自动执行所有操作。这在像 svn 这样的集中式客户端 - 服务器模型中可能是微不足道的。
But git is distributed. Your submodule may come from a totally different URL, with a totally different protocol. Most probably you don't event have push
access to the submodule's origin
repo, while you do for the main repo.
但是 git 是分布式的。您的子模块可能来自完全不同的 URL,具有完全不同的协议。很可能您无法push
访问子模块的存储origin
库,而您可以访问主存储库。
So there cannot be a recursive push.
所以不可能有递归推送。
Therefore the designers probably decided to avoid automatic recursion for submodules everywhere. Which is consistent, but a huge amount of pain.
因此,设计人员可能决定在任何地方避免子模块的自动递归。这是一致的,但巨大的痛苦。
So much so, that in a certain project we completely abandoned them and used subtree merges instead.
如此之多,以至于在某个项目中我们完全放弃了它们,而是使用了子树合并。