你能直接用Git子模块开发吗?

kel*_*oti 10 git git-submodules

我有两个项目(A和B).他们都使用项目Common.我希望通过子模块将Common包含在A和B中,因为那时我可以直接将A&B中的每个提交绑定到Common中依赖的提交.

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

我很确定我们不知道子模块应该如何使用,但是如果你不能直接在子模块中开发Common代码,那么这会不会让它更难开发?有人可以解释一下子模块的正确用法吗?

Von*_*onC 6

您可以直接从子模块开发(正如我在" 子模块的真实性质 "中所解释的那样).
但是每次在子模块中提交某些内容(并在某处发布)时,您都需要确保在父存储库中提交.

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

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

(实际上,如果Common它有自己的依赖关系,A或者B将取决于" ParentCommon"将引用Common它及其所有直接依赖关系)

除非你有一个结构势在必行,其中Common 必须是一个子目录A,我会建议第二个组织,这是更接近你C:\dev\A,C:\dev\Common一个.

实际上,我只选择一个深度依赖项,其中ParentA,我将所有依赖项(直接和间接)列为子模块.

这是因为,任何试图管理依赖关系的工具,您仍需要做出以下决策:

  • 依赖冲突(A取决于X哪些需求Z1,Y哪些需要Z2:Z您希望在项目中使用/编译哪个版本?)
  • 依赖关系覆盖(何时A取决于X哪些需求Z1,同时A也选择使用X2)
  • 依赖循环(A取决于B依赖于C哪些使用...... A!)


And*_*ack 5

子模块不是特别顺利的东西,就像你在这里打算的那样。您可能已经注意到,要在子模块中提交对项目的更改(从 Git v1.7 开始,可能是永久的),您需要:

  1. 在子模块中进行更改。
  2. 提交到子模块,获取新的 SHA 哈希。
  3. 使用新的哈希值更新外部项目的 .gitmodules 文件。
  4. 致力于外部项目。

如果您正在同步开发子模块和外部项目,这会很麻烦。就在混合代码库时更喜欢稳定的软件配置而不是简单性而言,这是“正确的方法”,但在这种情况下,命令序列是病态的。

然而,弹出为什么堆栈,使用子模块进行锁步开发可能表明几个更大的问题之一:

  • 您的子组件之间没有清晰的接口,并且实现细节会跨越边界泄漏。
  • 你的子组件没有一个经过深思熟虑的接口,所以当你解决一个更有趣的问题时,你不得不重新发明东西。
  • 您的界面是稳定和高质量的,但是您没有对子模块代码进行良好的 QA 流程,因此您在尝试完成其他工作的同时不断修复它。
  • (特别是如果 A 和 B 不断改变不同的东西)你的“共同”代码实际上比你想象的要小得多,或者应该以不同的方式划分。

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

但是,如果这些问题不存在,则可能是 git 对您来说是错误的工具。说出来让我很痛苦,但这绝对是一种可能性。