2011-02-15 55 views
10

我有两个项目(A & B)。他们都使用Common项目。我想通过子模块将Common包含到A & B中,因为那样我可以直接将每个提交都绑定在A & B中,它们在Common中依赖于哪些提交。你可以直接在Git子模块中开发吗?

在过去,我试图让我的团队使用这样的子模块,但我们无法让它顺利运行。我们正在从子模块内部开发通用代码&从子模块提交,但我们遇到了很多问题,我们恢复到将所有项目都放在同一目录下(C:\ dev \ A,C:\ dev \ Common)。

我很确定我们不知道应该如何使用子模块,但是如果您不能直接在子模块中开发通用代码,是否不会使开发更加困难?有人可以解释子模块的正确使用吗?

+0

非常密切相关:[高度耦合的git子模块](http://stackoverflow.com/questions/3712917/highly-coupled-git-submodules)。我还没有真正开始使用这个设置(它让我感到害怕,因为我的同事几乎不知道如何合并),但是有一些钩子可以帮助你。 – Cascabel 2011-02-15 18:58:55

+0

@Jefromi - 呃!我知道你和同事来自哪里。我有点犹豫是否继续这样做,除了我认为它能够在生产分支中修补常见代码中的错误方面增加很多确定性。感谢您的链接! – kelloti 2011-02-15 20:27:23

回答

6

您可以直接从子模块开发(如我在“true nature of submodules”中所解释的)。
但是,每次您在子模块中提交某些内容(并将其发布到某处)时,都需要确保在父库中提交。

现在你有两个子模块组织:

  • 递归包括
 
A 
    Common 
    (Common could depend itself on other dependencies) 
B 
    Common 
    ... 
  • 直接包括(仅直接依赖)
 
ParentA 
    A 
    Common 
    Other A dependencies 
ParentB 
    B 
    Common 
    Other B dependencies 

(实际上,如果Common有它自己的依赖AB将取决于“ParentCommon”,这将是指Common及其所有直接依赖)

除非你有一个结构势在必行,其中CommonA的一个子目录,我会推荐第二个组织,它更接近你的C:\dev\A,C:\dev\Common之一。

其实,我更喜欢只一个深度依赖,其中对于ParentA,我列出所有的依赖,直接和间接的,如子模块。

这是因为,与任何工具试图管理的依赖关系,你仍然需要做出决定:

  • 依赖性的冲突(A取决于X这就需要Z1,并且Y这需要Z2:哪个版本Z你想在你的项目中使用/编译吗?)
  • 依赖倍率(当A取决于X这就需要Z1,而A也选择使用X2
  • 依赖周期(其中A取决于B依赖于C它采用... A!)
+0

`直接包含'使用子模块吗? – kelloti 2011-02-15 18:15:42

4

子模块不是特别顺畅的工作,你打算在这里的方式。正如你可能已经注意到,承诺在一个子模块更改项目(如Git的V1.7,很可能永久),您需要:

  1. 使辅助模块的变化。
  2. 提交到子模块,获取新的SHA散列。
  3. 用新散列更新外部项目的.gitmodules文件。
  4. 承诺外部项目。

如果您以锁步形式开发子模块和外部项目,这很麻烦。这是“正确的方法”,只要在混合代码库时宁愿选择稳定的软件配置而不是简单的配置,但是在这种情况下,命令序列在病态上很长。

当弹出为什么叠加,虽然与子模块步调一致的发展可能表明的几个大问题之一:

  • 你没有你的子组件之间的界面清晰,并实现细节跨边界泄漏。
  • 对于您的子组件,您没有一个精心设计的界面,所以当您解决一个更有趣的问题时,您不得不重新创新。
  • 您的界面稳定且质量很高,但是您对子模块代码没有很好的QA过程,所以您不断尝试完成其他工作。 (特别是如果A和B不断变化不同的东西)你的“通用”代码实际上比你想象的要小得多,或者应该以不同的方式进行分组。

这些案件都不是一定真实的你,但这些都是导致你遇到的可怕步调一致子模块更新工作流程的问题之一。子模块工作的很好,当你可以几乎依赖共享库和头文件,但有一些令人信服的理由(例如奇怪的编译标志,必须一致)从源代码编译。我的方法是解决这些问题,如果它们是真正的根本原因。

如果这些问题不存在,然而,它可能是git是你的错误工具。这让我很痛苦,但这绝对是一种可能性。