JEP 357:从 Mercurial 迁移到 Git
概括
将 OpenJDK 社区的源代码存储库从 Mercurial (hg) 迁移到 Git。
目标
- 将所有单存储库 OpenJDK 项目从 Mercurial 迁移到 Git
- 保留所有版本控制历史记录,包括标签
- 根据 Git 最佳实践重新格式化提交消息
- 将jcheck、webrev和defpath工具移植到 Git
- 创建一个在 Mercurial 和 Git 哈希之间转换的工具
非目标
-
我们不会迁移多存储库 OpenJDK 项目,例如JDK 8 更新项目。如果这些项目合并到单个存储库中,则可以迁移到 Git。
-
我们不会改变JBS的 bug 系统。
-
我们不会积极停用现有的 Mercurial 存储库或采取其他操作来过早地使指向存储库的许多 URL 失效,例如 JBS 中错误的注释中。现有的 Mercurial 主存储库将至少在规定的过渡期内保留为只读存档。从长远来看,Mercurial URL 到 Git URL 的转换器可能会到位。
-
此 JEP 没有解决 OpenJDK Git 存储库是自托管还是由外部提供商托管的问题。该问题是 JEP 369 的主题:迁移到 GitHub。
-
我们不会建议更改当前的 JDK 开发流程,尽管此 JEP 确实支持此类更改。
动机
迁移到 Git 的三个主要原因:
- 版本控制系统元数据的大小
- 可用工具
- 可用托管
转换后的存储库的初始原型显示版本控制元数据的大小显着减小。例如,使用 Git 时,存储库.git
的目录jdk/jdk
约为 300 MB,.hg
使用 Mercurial 时,存储库的目录约为 1.2 GB,具体取决于所使用的 Mercurial 版本。元数据的减少可以保留本地磁盘空间并减少克隆时间,因为需要通过网络传输的位数更少。 Git 还具有_浅克隆_功能,仅克隆部分历史记录,从而为不需要整个历史记录的用户提供更少的元数据。
除了 Mercurial 之外,还有更多与 Git 交互的工具:
-
所有文本编辑器都具有 Git 集成,无论是本机还是插件形式,包括Emacs(magit插件)、Vim(fugitive.git插件)、VS Code(内置)和Atom(内置)。
-
几乎所有集成开发环境 (IDE) 都附带开箱即用的 Git 集成,包括IntelliJ(内置)、Eclipse(内置)、NetBeans(内 置)和Visual Studio(内置)。
-
有多个桌面客户端可用于与本地 Git 存储库交互。
最后,有许多选项可用于托管 Git 存储库,无论是自托管还是作为服务托管。
描述
我们已经制作了一个将 Mercurial 存储库转换为 Git 存储库的程序原型。它使用该git-fast-import
协议将 Mercurial 变更集导入 Git,并调整现有提交消息以与 Git 最佳实践保持一致。 Mercurial 存储库的提交消息jdk/jdk
具有以下结构:
JdkHgCommitMessage:BugIdLine + SummaryLine?ReviewersLine 贡献者行?
BugIdLine : /[0-9]{8}/
": "
文本摘要行:
"Summary: "
文本ReviewersLine:
"Reviewed-by: "
用户名(", "
用户名)*“\n
”贡献者行:
"Contributed-by: "
文本用户名:/[az]+/
文本:/[^\n]+/“
\n
”
Git 存储库的提交消息的jdk/jdk
结构略有不同:
JdkGitCommitMessage:BugIdLine +正文?拖车
BugIdLine : /[0-9]{8}/ ": "文本
正文:空白行 文本
*
预告片:BlankLine 合著者?审稿人
共同作者:(BlankLine 共同作者)+
共同作者:
"Co-authored-by: "
实名<
邮箱>
审稿人:
"Reviewed-by: "
用户名(", "
用户名)*“\n
”空白行= "\n"
用户名:/[az]+/
文本:/[^\n]+/“\n”
改变消息结构的原因是:
-
Git CLI 工具强烈鼓励使用标题(一行后跟一个空行)。
-
标题的使用可以实现自由形式的正文。
-
Git 生态系统识别_预告片_,即用换行符与正文分隔的行。例如,GitHub和GitLab都可以识别
Co-authored-by:
预告片,并且会识别该提交有多个作者。
Git 使用提交元数据中的附加字段来表示提交的提交者,以区别于作者。我们将使用提交者字段来表示赞助:在赞助提交的情况下,作者将在author
提交字段中命名,赞助商将在该committer
字段中命名。如果赞助商也是共同作者,那么Co-authored-by
将添加适当的预告片,这是我们在现有 Mercurial 消息结构中无法捕获的情况。
不同提交者字段的另一种可能用途是识别从功能版本到更新版本的向后移植提交,这通常是由原始提交作者以外的其他人完成的。
作者和提交者字段的内容将采用_Real-name_ <
Email>
的形式,因为并非每个提交作者都是OpenJDK Author。将使用一个特殊的电子邮件地址来表明作者或提交者也是 OpenJDK 作者:<openjdk-username>@openjdk.org
。
以下是 Git 提交消息的示例:
76543210: Crash when starting the JVM
Fixed a tricky race condition when the JVM is starting up by using a Mutex.
Co-authored-by: Robin Westberg <rwestberg@openjdk.org>
Reviewed-by: darcy
此类提交的作者和提交者字段将是:
Author: Erik Duveblad <ehelin@openjdk.org>
Commit: Erik Duveblad <ehelin@openjdk.org>
在转换过程中,当作者_未_在线上列出时,提交将被视为赞助Contributed-by:
。在这种情况下,上线的第一个人Contributed-by:
将被视为作者,发起人将被视为提交者,任何其他贡献者将被视为共同作者。
转换后的存储库的示例可在https://github.com/openjdk/上找到。
工具
我们已经制作了 Mercurial 工具jcheck、webrev和defpath的向后兼容端口原型。
我们还制作了新工具的 原型git-translate
。该工具使用一个名为 的文件.hgcommits
,该文件由转换工具生成并提交到 Git 存储库。该文件包含一系列行,每行包含两个十六进制哈希值:第一个是 Mercurial 变更集的哈希值,第二个是转换该 Mercurial 变更集后生成的 Git 提交的哈希值。该工具git-translate
只是查询文件.hgcommits
:
$ git translate --to-hg 0f8927e8b5bf88e7e2c7c453b4cd75e01eeccaf4
bd613b97c7c88658801b0f0c603a55345dfef022
$
备择方案
继续使用 Mercurial。
测试
如上所述,映射文件.hgcommits
可用于验证给定提交的所有元数据是否已正确转换,以及两个提交的源代码树是否相同。
风险和假设
突出的风险是转换过程中会引入错误。通过如上所述的严格验证可以降低该风险。