假设我有四个名为Core,A,B,Super的项目.依赖树是这样的:
Super ---> Core |-> A -> Core |-> B -> Core
我希望每个项目都是独立的,也就是说,我希望能够自己签出并编译每个项目(当然每个项目都依赖于它们).
我考虑过将每个项目映射到一个存储库,然后将依赖项与子模块一起引用,但是我看到了这种方法的以下问题:
当检查Super及其所有依赖项时,我最终会得到三个Core副本.
由于子模块是完全独立的,因此这三个副本中的每一个都可能指向Core的不同版本,这将是一个烂摊子.
那么......我错过了什么吗?我是否误解了git子模块或误用了它们?有没有其他解决方案来解决这个问题(除了诉诸二进制依赖)?
您刚刚发现Git子模块缺少重写的依赖项:
如果Super依赖于Core,它对Core的依赖应该"覆盖"A和B对Core的依赖.
模仿的唯一方法是以你的方式创建你的超级项目,
并删除A和B的子模块Core
(意思是Super现在依赖于A'和B',A'是没有Core的A, B'没有核心B)
git存储库应该是相当原子的,就像每个存储库是一个特定目的的独立实体一样.除了合并项目A和B之外,超级项目的目的是什么?如果没有任何独特的东西(即不在A,B或Core中的文件)那么它是相当多余的.
编辑:因为git子模块在我工作的一个地方特别痛苦,我们建立了自己的依赖系统,通过文本文件跟踪依赖的回购.我们将其设置为始终跟踪分支的头部,而不是特定的提交.
我们能够设置我们所有的项目,好像它们是Super项目的一部分,如下所示:
Super |-A |-B |-Core
项目将使用相对路径相互引用,例如../A/include.h
.检查回购A将无法工作,您将不得不创建另一个"超级"回购只用于A:
AWorking |-A |-Core
编辑在git中这种行为的另一个原因是它无法跟踪根目录下的内容(即在包含.git文件夹的文件夹上方),如果你想要你的超级项目和子项目肯定是必需的指的是相同的存储库.
我认为这里的问题是Git的设计与你想要解决的问题之间的不匹配.
Git很适合追踪树木.项目之间的依赖关系可以(并且可能)形成图形.树是图形,但图形不一定是树.由于您的问题是如何有效地表示图形,因此树不是工作的最佳工具.
这是一种可行的方法:
git项目有一个.gitmodules目录,它记录"提示",说明提交可能依赖的项目,可以找到它们的位置,以及项目中应该插入的路径.(http://osdir.com/ml/git/2009-04/msg00746.html)
您可以添加一个脚本,从一组项目中读取此信息,将每个项目的.gitmodules文件中的提示映射到文件系统中实际放置这些项目的位置,然后从git期望的路径添加符号链接检查子模块到相应项目的实际文件系统位置.
这种方法使用符号链接来打破Tree模型并构建Graph.如果我们直接在git repos中记录链接,我们将在各个项目中记录特定于我们本地设置的相对路径,并且项目不会像您想要的那样"完全独立".因此,脚本动态构建符号链接.
我认为这种方法可能会以不合需要的方式干扰git,因为我们已经采取了希望找到一件事的路径,而是将其他东西放在那里.也许我们可以.gitignore符号链接路径.但是现在我们将这些路径写下来两次并且违反DRY.在这一点上,我们还远远没有假装使用子模块.我们可以在每个项目的其他地方记录依赖项,并保留git期望的.gitmodules文件.所以我们将构建我们自己的文件,例如.dependencies,每个项目都可以在那里声明它的依赖关系.我们的脚本将在那里看,然后去构建它的符号链接.
嗯,我想我可能刚刚描述了一个特殊的包管理系统,它有自己的轻量级包格式:)
megamic的建议似乎是对我使用git子模块的好方法.我们只处理在这里跟踪Set而不是Graph,并且Set很容易适合树.一层深度的树本质上是父节点和一组子节点.
正如您所指出的,这并不能完全解决您问题中所述的问题.我们可以打破两种不同类型的"这与我们可能感兴趣的信息":1.来自项目版本的声明(可能是项目的作者)说"我需要项目Y的版本X"2 .您自己的构建设置使用的语句"我已经使用这组项目版本成功测试了整个系统"
megamic的答案解决了(2)但是对于(1)我们仍然希望项目告诉我们他们的依赖是什么.然后我们可以使用(1)中的信息来计算我们最终记录为(2)的那些版本集.这是一个复杂的问题,需要保证自己的工具,这将我们带回到包管理系统:)
据我所知,大多数优秀的包管理工具都是针对特定语言或操作系统的用户而设计的.请参阅Bundler,了解ruby世界中的'gem'包,并在Debian世界中使用'.deb'包.
如果有人知道一个良好的语言中立,操作系统中立的解决方案,非常适合'polyglot'(http://blog.heroku.com/archives/2011/8/3/polyglot_platform/)编程项目,我会很感兴趣!我应该将其作为一个问题发布.