关于Java:何时应将多模块项目拆分为单独的存储库树?

关于Java:何时应将多模块项目拆分为单独的存储库树?

When should a multi-module project to split into separate repository trees?

当前,我们有一个项目,其标准的Subversion存储库布局为:

./ trunk
./分支
./tags

但是,随着我们逐步走上OSGi和模块化项目的道路,我们最终得到了:

./ trunk / bundle / main
./trunk/bundle/modulea
./trunk/bundle/moduleb
./tags/bundle/main-1.0.0
./tags/bundle/main-1.0.1
./tags/bundle/modulea-1.0.0

尽管我开始怀疑我们是否应该将构建/存储库重构为类似以下的内容,但它仍然按顺序构建所有模块:

./ bundle / main / trunk
./bundle/main/tags/main-1.0.0
./bundle/main/tags/main-1.0.1
./bundle/modulea/trunk
./bundle/modulea/tags/modulea-1.0.0

在这种模式下,我会想象每个模块都将自己构建,并将其二进制文件存储在存储库(Maven,Ivy或Subversion存储库本身的另一个路径)中。

项目布局一旦模块化,是否存在有关项目布局的准则或"最佳实践"?


Subversion本书包含两个部分:

  • 仓库布局
  • 规划存储库组织

有关该主题的博客条目:" Subversion存储库布局"

一个简短的答案:虽然您的里程会有所不同(每种情况都是个别的),但是您的/bundle/<project>/(trunk|tags|branches)方案相当普遍,并且很可能对您有效。


这很大程度上取决于个人喜好,但是我发现以下结构适用于包含许多模块的大型项目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
branches
  project-name
    module1
      branch-name
    module2  
      possibly-another-branch-name
    branch-name-on-a-higher-level-including-both-modules
      module1
      module2
tags
  ... (same as branches)
trunk
  project-name
    module1
    module2

我还经常在包含许多项目的大型存储库中使用该结构,因为将所有项目保留在同一存储库中可以使交叉引用项目以及在它们之间(以及历史记录)之间共享代码更加容易。

我喜欢从一开始就将结构与根主干,标签和分支文件夹一起使用,因为根据我的经验(对于包含许多项目的大型存储库),许多子项目和模块永远不会有单独的标签或分支,因此存在无需为其创建文件夹结构。这也使开发人员可以更轻松地检出存储库的整个主干,而不必获取所有的标记和分支(他们通常不需要它们)。

我想这是项目或公司政策的问题。如果每个项目都有一个存储库,或者给定的开发人员一次只能在存储库中的单个项目上工作,则根主干可能没有多大意义。


我的两分钱...

我只想强调SVN文档中的注释(已在另一个答案中,相同的线程中引用过)http://svnbook.red-bean.com/en/1.4/svn.reposadmin.planning.html#svn。 reposadmin.projects.chooselayout

节选引用以下结构:
/
树干/
calc /
日历/
电子表格/
a€|
标签/
calc /
日历/
电子表格/
a€|
分支机构/
calc /
日历/
电子表格/

"关于这种布局,没有什么特别不正确的,但是对于您的用户而言,它可能看起来还是不那么直观。尤其是在大型,多项目的情况下,并且有许多用户,这些用户可能只熟悉一两个仓库中的所有项目。但是"分支机构的兄弟"倾向于不强调项目的个性,而是将整个项目集中为一个整体,但这是一个社会问题。我们喜欢我们最初建议的安排实际原因–当存在一个存储整个项目的过去,现在,标记和分支历史的单一存储库路径时,就更容易询问(或修改或迁移到其他地方)单个项目的整个历史。还有那个项目。"

就我自己而言,我倾向于对此表示强烈赞同,并倾向于以下布局:
/
实用程序/
calc /
树干/
标签/
分支机构/
日历/
树干/
标签/
分支机构/
a€|
办公室/
电子表格/
树干/
标签/
分支机构/

原因很简单,当只想标记特定子集时,标记整个项目集是不切实际的。

让我们举个例子:如果project-1依赖moduleA v1.1和moduleB v2.3,我不希望新的moduleA v2.x出现在标签中。实际上,当在几天,几周,几月后返回此标记的发行版时,我将被迫在标记为project-1的版本中打开束描述符,以读取实际所需的moduleA版本。

此外,如果我必须将此发行版源的特定备份备份到CD上,我只想导出此标签而无需下载数百兆的无关内容。

那只是我的两分钱。


我已经在StackOverflow版本控制结构问题中回答了类似的问题。实际上,由于我们进行了大量的OSGi开发并且有很多捆绑销售产品,因此它实际上更适合这里。我必须回应Anders Sandvig的评论:将主干/标签/分支保持在根级别,因为您将只分支有限的一组模块。它还不会干扰单独构建的模块。

我不会复制以前的答案,但这与该问题完全相关。


推荐阅读