跳到主要内容

JEP 296:将 JDK 森林合并到单个存储库中

概括

将 JDK 森林的众多存储库合并到一个存储库中,以简化和简化开发。

非目标

将 FX 源添加到 JDK 林不是提案的一部分。

动机

多年来,JDK 的完整代码库已分解为众多 Mercurial 存储库。 JDK 9 中有八个存储库:root、corba、hotspot、jaxp、jaxws、jdk、langtools 和 nashorn。

虽然这种多存储库模型提供了一些优点,但它也有许多缺点,并且在支持各种所需的源代码管理操作方面表现不佳。特别是,不可能跨相互依赖的变更集的存储库执行原子提交。例如,如果今天单个错误修复或 RFE 的代码跨越 jdk 和 hotspot 存储库,则无法在托管这两个不同存储库的林中自动完成对这两个存储库的更改。跨越多个存储库的更改是很常见的情况;超过 1,100 个错误 ID 已在 JDK 林中的存储库中重复使用。 1,100 多个仓库交叉错误只是逻辑上仓库交叉错误数量的下限,因为一些工程师使用单独的错误 ID 来推送到不同的仓库。

Mercurial 存储库的划分与工程的统一之间的这种不匹配削弱了现代源代码管理的主要好处之一:跟踪文件集而不是单个文件的更改。因此,SCM 事务和逻辑事务之间的这种不匹配使得 Mercurial bisect 等工具的使用变得复杂。

各个存储库没有独立于整个 JDK 的开发周期;所有存储库都与 JDK 升级周期同步推进。存储库的多样性给新开发人员带来了不必要的障碍,并导致了诸如“获取源代码”脚本之类的变通方法。

描述

为了解决这些问题,开发了综合森林的原型。原型可在以下位置获得:

http://hg.openjdk.java.net/jdk10/consol-proto/

一些用于创建原型的支持转换脚本作为 附加unify.zip

在原型中。八个存储库已使用自动转换脚本合并为一个存储库,该脚本保留每个文件级别的历史记录,并在用于标记 JDK 升级的标签上同步整合的林。变更集注释和创建日期也被保留。

该原型还有另一个级别的代码重组。在合并的森林中,Java 模块的代码通常合并在单个顶级 src 目录下。例如,今天在 JDK 森林中有基于模块的目录,例如

$ROOT/jdk/src/java.base
...
$ROOT/langtools/src/java.compiler
...

在合并林中,该代码的组织方式如下

$ROOT/src/java.base
$ROOT/src/java.compiler
...

因此,在合并和 src 目录组合之后,从存储库的根开始,模块中源文件的相对路径将被保留。

对测试目录进行了类似但不太激进的重组

$ROOT/jdk/test/Foo.java
$ROOT/langtools/test/Bar.java

$ROOT/test/jdk/Foo.java
$ROOT/test/langtools/Bar.java

由于该作品目前只是原型,并非所有部分都完全完成,并且某些区域的配合和表面处理还可以改进。 HotSpot C/C++ 源代码与模块化 Java 代码一起移至共享 src 目录。

虽然回归测试将在原型的当前状态下运行,但 jtreg 配置文件的进一步整合是可能的,并且可能在将来完成。

备择方案

一种替代方法是简单地保留当前的存储库集。当移动到单个存储库时,部分或全部存储库的历史记录可能已被删除,但这被拒绝了。曾考虑合并存储库的核心子集,但因支持单个存储库的简单性而被拒绝。

测试

为了验证文件内容,对于每个升级标签,使用脚本来验证该标签处的分割林的内容是否与该标签处的统一存储库的内容相匹配。对于最近的 JDK 9 标签,比较了同一标签下的分割林和合并林的构建;只有微小且可以解释的差异。

风险和假设

上述测试应该可以减轻文件损坏和错误构建的最严重风险。虽然整合所需工作的主要部分已在原型中完成,但在整合投入生产之前,各种较小的支持功能可能尚未完成。合并前和合并后的代码库在 Mercurial 意义上并不相关。差异(具有适当管理的路径)必须用于前向和后向移植,而不是导出和导入变更集。