为什么`git checkout`不会自动执行`git submodule update --recursive`?

时间:2014-03-11 14:03:39

标签: git git-submodules

有人请帮我理解git中的子模块。我知道他们在互联网上受到了很多抨击但是因为我认为git开发人员是聪明人,所以当前的行为必须有一个理由 - 也许是一种解决我的问题的方法。

所以,我有一个项目和一些子模块。该项目有不同的分支,如:

  • MyApp_version2
  • MyApp_version3
  • MyApp_version4
  • MyApp_liteversion
  • MyApp_development

我的子模块经常不会更新(可能每周一次),所以我对他们not being attached to the head of the submodule repository automatically没问题。

但是,当我查看旧分支时 - 因为我需要修复旧版软件中的错误 - 我还需要更新子模块。

为什么我需要这样做?

我希望git像svn一样工作。当我在主回购中投入工作时,我希望git能够按照以下思路思考:"好吧,他现在想要完成他的工作。我可以看到子模块当前处于修订版abc中,所以当他在将来某个时候回到这个提交时他可能希望子模块再次出现在同一个版本中。"

在主存储库中返回3年时,我无法看到您希望子模块保留在当前版本的情况。但是,这个实施必须有理由,对吗?

我真的很想知道你们是否知道这背后的想法,但无论如何我真的想要一个解决方案。有没有办法告诉git:"我想用这些子模块提交这项工作。如果我在某个时候回到这个状态,我希望在正确的版本中检查子模块。"

澄清示例

我的主存储库是一个需要使用SSL的应用程序,我找到了一个我作为子模块添加的SSL库(libSSL)。

2010年10月31日,我在我的主存储库(2fd4e1)中创建了一个提交,而子模块指向了libSSL版本3(c67a2d)。

时间过去了,libSSl更新到版本34,我调整我的代码,生活得很好。

2013年5月14日,我创建了一个新的提交(28fced)和子模块指向最新版本的libSSL(849ee1)。

但是,如果我签出2fd4e1,即使原始提交是使用c67a2d创建的,我的子模块仍将保持在849ee1。 Git知道我使用c67a2d进行了原始提交,并且我不知道你怎么可能想要另一个子模块,而不是创建原始提交的子模块。

3 个答案:

答案 0 :(得分:18)

听起来你想做的事情可以通过git v2.13使用--recurse-submodules的新git checkout选项来实现。从git-checkout手册页:

  

- [无糖]递归-子模块

     

使用--recurse-submodules将根据超级项目中记录的提交更新所有初始化子模块的内容。如果子模块中的局部修改将被覆盖,则除非使用-f,否则检出将失败。如果没有使用(或--no-recurse-submodules),子模块的工作树将不会更新。

另见relevant git mailing list message about that new option

答案 1 :(得分:0)

通过使用来简化您的快捷方式/别名:

alias checkitout='git checkout $1; git submodule --recursive'

答案 2 :(得分:-1)

你基本上希望git以递归方式自动为所有子模块执行所有操作。在像svn。

这样的集中式客户端 - 服务器模型中,这可能是微不足道的

但是git是分发的。您的子模块可能来自完全不同的URL,具有完全不同的协议。很可能你没有事件push访问子模块的origin回购,而你做主回购。

所以不能进行递归推送。

因此,设计人员可能决定避免各处子模块的自动递归。这是一致的,但却是一种巨大的痛苦。

这么多,在某个项目中我们完全放弃了它们并使用了子树合并。