Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 385 – 从 Subversion 迁移到 Mercurial

作者:
Dirkjan Ochtman <dirkjan at ochtman.nl>, Antoine Pitrou <solipsis at pitrou.net>, Georg Brandl <georg at python.org>
状态:
最终版
类型:
流程
创建:
2009 年 5 月 25 日

目录

动机

在决定切换到 Mercurial DVCS 后,实际的迁移仍然需要执行。对于像 Python 这样大型分布式项目版本控制系统这样的重要基础设施来说,这是一项重大工作。本 PEP 试图描述需要采取的步骤以供进一步讨论。它与 PEP 347 相似,后者讨论了迁移到 SVN 的事宜。

为了最大限度地利用 hg,我们希望进行高保真转换,这样 (a) 尽可能保留 svn 元数据,以及 (b) 将所有元数据转换为 Mercurial 中常见的格式。这样,为 Mercurial 编写的工具就可以得到最佳利用。为了做到这一点,我们希望使用 hgsubversion 软件进行初始转换。此 hg 扩展专注于提供高质量的从 Subversion 到 Mercurial 的转换,用于双向对应,这意味着它不会像其他解决方案那样丢弃大量可用的元数据。

这种转换似乎也是重新考虑仓库内容和确定某些内容是否仍然有价值的好时机。本着这种精神,以下部分还建议丢弃一些旧的元数据。

时间线

转换里程碑的当前时间表

  • 2011 年 2 月 24 日:hg.python.org 上的测试仓库可用

    所有提交者将被允许(并鼓励)向 Subversion 仓库提交测试提交。一旦最终转换完成,测试仓库和所有测试提交都将被删除。将为测试仓库安装服务器端钩子,以便测试 buildbot、diff-email 和空白检查集成。

  • 2011 年 3 月 5 日:最终转换(暂定)

    对 Subversion 分支(现在在 Mercurial 中维护)的提交将被阻止。在所有基础设施都确保在他们切换到新的仓库后能够正常工作之前,开发者应该避免向 Mercurial 仓库推送代码。

迁移计划

分支策略

Mercurial 有两种基本的分支使用方式:克隆分支,每个分支都保存在一个独立的仓库中,以及命名分支,每个修订版都保留元数据以记录它属于哪个分支。前者使区分分支更容易,但代价是客户端需要更多磁盘空间。后者使在分支之间切换更容易,但所有分支名称都是历史的持久部分。[1]

命名分支和克隆分支之间的区别

  • 不同(维护)克隆中的标签在本地克隆中不可用
  • 使用命名分支的克隆会更大,因为它们包含更多数据

我们建议对发布分支使用命名分支,对特性分支采用克隆分支。

历史管理

为了最大限度地减少转换过程中信息丢失,我们建议提供多个仓库作为转换结果

  • 一个修剪到主干(以及 py3k)的仓库,以及过去和现在的维护分支——这被称为“工作”仓库,也是开发继续进行的地方。该仓库包含开发工作所需的所有历史记录,包括使用 1990 年以前的更改注释源文件和其他常见的历史挖掘操作。

    该仓库中的 default 分支是 Subversion 中称为 py3k 的分支,而 Subversion 主干则保留了 legacy-trunk 的分支名称;但在 Mercurial 中,这个分支将被关闭。发布分支以它们的 major.minor 版本命名,例如 3.2

  • 一个包含 Subversion 仓库(实际上是它的 /python 子目录)的完整、未编辑转换的仓库——这被称为“历史”或“存档”仓库,并将作为只读资源提供。[2]
  • 每个活跃的特性分支都还有一个仓库;“活跃”意味着至少有一名核心开发人员要求提供该分支。每个这样的仓库都将包含特性分支和来自主干的所有祖先变更集(来自 SVN 中的 trunk 和/或 py3k)。

由于所有分支都存在于历史仓库中,因此以后可以随时将它们提取为独立的仓库,如果需要的话。

SVN 修订版号、Mercurial 变更集和 SVN 分支名称之间的最终修订版映射将存储在 Misc 目录中的文件中。其格式如下

[...]
88483 e65daae6cf4499a0863cb7645109a4798c28d83e issue10276-snowleopard
88484 835cb57abffeceaff0d85c2a3aa0625458dd3e31 py3k
88485 d880f9d8492f597a030772c7485a34aadb6c4ece release32-maint
88486 0c431b8c22f5dbeb591414c154acb7890c1809df py3k
88487 82cda1f21396bbd10db8083ea20146d296cb630b release32-maint
88488 8174d00d07972d6f109ed57efca8273a4d59302c release27-maint
[...]

转换标签

SVN 标签目录包含许多旧的内容。其中一些实际上并不是完整的标签,而只包含仓库的一小部分。所有发布标签都将被保留;其他标签将根据开发者社区的要求进行包含。我们建议将标签命名方案统一起来,采用以下格式:v3.2.1a2

作者映射

为了以 hg 中常见的形式提供用户名(以‘First Last <user@example.org>’ 格式),我们需要一个作者映射来将 cvs 和 svn 用户名映射到真实姓名和他们的电子邮件地址。我们在迁移工具仓库中有一个完整的映射版本(为了避免向收集者泄露地址而不对公众开放)。它里面的电子邮件地址可能已经过时了;这肯定会发生,虽然如果能尽力让尽可能多的人审查一下过时的地址会很好。当前版本似乎还存在一些编码问题。

生成 .hgignore

.hgignore 文件可以在 Mercurial 仓库中使用,以帮助忽略不适合版本控制的文件。它通过使用几种可能的模式匹配形式来做到这一点。当前的 Python 仓库已经包含一个基本的 .hgignore 文件,以帮助使用 hg 镜像。

由于当前的 Python 仓库已经包含一个 .hgignore 文件(用于 hg 镜像),因此我们将直接使用它。关于生成文件的完整历史记录进行了讨论,但认为不切实际(因为这样做相对困难,而且收益很小,因为忽略对于旧的修订版来说并不那么重要)。

仓库大小

当前 Python 仓库的裸转换结果大小为 1.9 GB;虽然这比 Subversion 仓库 (2.7 GB) 小,但它仍然不可行。

通过对工作仓库进行修剪,以及通过一个称为“revlog 重排序”的过程,可以使大小更易于管理,该过程可以非常有效地优化内部 Mercurial 存储的布局。

完成所有优化后,工作仓库的大小约为 180 MB,磁盘空间约为 180 MB。克隆时通过网络传输的数据量估计约为 80 MB。

其他仓库

svn.python.org 的“projects”仓库中托管了许多其他项目。“peps”目录将与主要的 Python 仓库一起进行转换。Richard Tew 已经表示希望 Stackless 仓库也进行转换。svn.python.org 仓库中还有哪些项目应该进行转换?

目前,已经对 Jython 仓库进行了初步的转换尝试。不幸的是,hgsubversion 的当前尖端在某个时间点失败了。正在进行调查。

其他希望转换为 Mercurial 的仓库可以在主 Python 迁移完成后向我宣布,我会满足他们的需求。

基础设施

hg-ssh

开发人员应该通过 ssh 访问仓库,类似于当前的设置。可以使用公钥来授予用户对共享 hg@ 帐户的访问权限。在 hg.python.org 上还设置了一个 hgwebdir 实例,以便于浏览和只读访问。它被配置成开发者可以轻松地启动新的克隆(用于长期特性,这些特性可以从在单独的仓库中进行开发中获益)。

此外,核心开发人员还可以直接创建公共仓库,虽然还没有确定将强制执行哪种命名方案

$ hg init ssh://hg@hg.python.org/sandbox/mywork
repo created, public URL is http://hg.python.org/sandbox/mywork

钩子

目前正在使用许多钩子。应该开发和部署这些钩子的 hg 等效项。以下钩子正在使用

  • 检查空白:一个用于在空白不符合 Python 代码库规则的情况下拒绝提交的钩子。在一个变更集中,只检查尖端(这允许清理来自第三方仓库的更改提交)。我们还可以提供一个空白钩子,供用户在客户端仓库中使用;它可以警告空白问题和/或从更改的行中截断尾随空白。
  • 推送邮件:电子邮件将包含推送至公共仓库的每个变更集的差异,包括推送变更集的用户名(这并不一定与变更集中记录的作者相同)。
  • buildbots:python.org 构建主服务器将收到推送至 cpython 仓库的每个变更集的通知,并将针对变更集所在的每个分支在每个构建从属服务器上触发适当的构建。

hooks 仓库 包含这些服务器端钩子的 Mercurial 移植版本,以及一些额外的钩子

  • 检查分支头:一个用于拒绝创建现有分支上的新头的推送的钩子。然后,推送者必须合并多余的头,并尝试再次推送。
  • 检查分支:一个用于拒绝不在允许的命名分支上的所有变更集的钩子。当我们想要创建新的维护分支时,此钩子的白名单将需要更新。
  • 检查行尾:一个基于 eol 扩展 的钩子,用于拒绝提交包含错误行尾的文件的所有变更集。然后,必须剥离提交并重新执行,可能需要在提交者的计算机上启用 eol 扩展

一个额外的钩子可能会有益

  • 检查贡献者:在当前设置中,所有变更集都带有提交者的用户名,这些提交者必须签署贡献者协议。如果我们保留一个注册贡献者的列表,我们可能希望使用一个钩子来检查提交者是否为贡献者。然后,钩子可能会警告那些推送包含来自未知贡献者的变更集的一组修订版的用户。

行尾转换

关于 Mercurial 缺乏行尾转换支持的讨论,该支持最初由 win32text 扩展 提供,导致了新 eol 扩展 的开发,该扩展支持在文件级对行尾约定进行版本化管理,类似于 Subversion 的 svn:eol-style 属性。此信息存储在一个名为 .hgeol 的版本化文件中,该文件已签入 Subversion 仓库。

服务器端还存在一个钩子,用于拒绝引入不一致换行符数据的任何变更集(见上文)。

hgwebdir

应该设置一个或多或少是标准的 hgwebdir 安装。我们可能想出一个与 Python 网站相匹配的样式。

已经编写了一个小型 WSGI 应用程序,它可以查找 Subversion 修订版并重定向到给定变更集的相应 hgweb 页面,无论转换后的修订版最终位于哪个仓库(因为一个大型 Subversion 仓库被转换为多个 Mercurial 仓库)。它也可以通过十六进制 ID 查找 Mercurial 变更集。

roundup

通过将 Roundup 指向上述查找脚本的 URL,SVN 修订版的链接将继续起作用,并且还可以创建 Mercurial 变更集的链接,而无需提供仓库和变更集 ID。

迁移后

代码获取

迁移后,hgwebdir 将位于 hg.python.org。对于许多组织来说,这是一个公认的标准,并且与 svn.python.org 非常类似。工作仓库可能位于 http://hg.python.org/cpython/,例如,存档仓库位于 http://hg.python.org/cpython-archive/。为了获得写入权限,开发人员必须使用 ssh,例如 ssh://hg@hg.python.org/cpython/

code.python.org 也被提议作为主机名。我们认为在主机名中使用 VCS 名称比较好,因为它可以避免混淆:应该明确的是,你不能对 hg.python.org 使用 svn 或 bzr。

hgwebdir 已经可以为每个变更集提供 tarball。这消除了对每日快照的需求;我们只需将用户指向 tip.tar.gz 即可,这意味着他们将获得最新版本。如果需要,我们甚至可以使用 buildbot 结果指向最后一个成功的变更集。

Python 特定文档

hg 自带了很好的内置文档(可以通过 hg help 获取)和一个 wiki,其中充满了有用的信息和技巧,更不用说一本受欢迎的 书籍(可以在线阅读)。

除此之外,最近进行了全面修订的 Python 开发人员指南 已经有一个分支,其中包含了有关 Mercurial 的说明,而不是 Subversion;一个在线 此分支的构建 也可用。

建议的工作流程

我们建议使用两种工作流程来迁移多个分支之间的补丁。

对于在 2.x 或 3.x 分支内的迁移,我们建议始终将补丁提交到它首先适用的最旧分支。然后,可以使用 hg merge 将生成的变更集合并到该系列中所有更新的分支(2.x 或 3.x)。如果它不能按原样应用到更新的分支,则可以使用 hg revert 轻松恢复到新的分支原生头,将补丁的替代版本(如果适用)打入,然后提交合并。这里的前提是,来自该系列中较旧分支的所有变更集最终都会合并到该系列中所有更新的分支。

结果是,这提供了最轻松的合并过程。这意味着,在一般情况下,人们必须考虑将补丁应用到的最旧分支,然后才能真正应用它。通常,只有两个分支之一:最新的维护分支和主干,除了适用于安全修复模式下较旧分支的安全修复之外。

对于将 bug 修复从 3.x 合并到 2.7 维护分支(2.6 和 2.5 处于安全修复模式,它们的维护将继续在 Subversion 仓库中进行),变更集应该以其他方式移植(而不是合并)。transplant 扩展、导入/导出和 bundle/unbundle 在这里同样有效。

选择这种方法可以使 3.x 不必承载从分支出来后所有 2.x 的历史,这意味着克隆的大小不会那么大,合并也不会那么复杂。

Subversion 的未来

迁移后,Subversion 仓库会怎么样?由于 svn 服务器包含一堆仓库,而不仅仅是 CPython 仓库,因此它可能会保留一段时间,因为并非所有项目都需要迁移,或者其他项目迁移需要更长的时间。为了防止人们落后,我们可能需要将迁移后的项目从仓库移动到一个新的、只读的仓库,并使用一个新的名称。

构建标识

Python 目前提供 sys.subversion 元组,以允许 Python 代码找出它运行的 Python 版本的具体信息。当前版本看起来像这样

  • (‘CPython’, ‘tags/r262’, ‘71600’)
  • (‘CPython’, ‘trunk’, ‘73128M’)

另一个值是从 C API 中的 Py_GetBuildInfo() 返回的,并作为 sys.version 的一部分提供给 Python 代码

  • ‘r262:71600, Jun 2 2009, 09:58:33’
  • ‘trunk:73128M, Jun 2 2009, 01:24:14’

我建议修订版标识符将是 hg 修订版哈希的简短版本,例如 ‘dd3ebf81af43’,如果构建它的工作目录被修改,则会附加 ‘+’(而不是 ‘M’)。这反映了 hg id 命令的输出,该命令旨在用于这种类型的用法。sys.subversion 值也将被重命名为 sys.mercurial 以反映 VCS 的更改。

对于标签/分支标识符,我建议 hg 将检查当前签出的修订版上的标签,如果存在标签(‘tip’ 不算),则使用该标签,否则使用分支名称。sys.subversion 变成

  • (‘CPython’, ‘v2.6.2’, ‘dd3ebf81af43’)
  • (‘CPython’, ‘default’, ‘af694c6a888c+’)

构建信息字符串变成

  • ‘v2.6.2:dd3ebf81af43, Jun 2 2009, 09:58:33’
  • ‘default:af694c6a888c+, Jun 2 2009, 01:24:14’

这反映了 hg 中的默认分支名为 ‘default’,而不是 Subversion 的 ‘trunk’,并且反映了提议的新的标签格式。

Mercurial 还允许找出最新的标签以及当前变更集与该标签之间的变更集数量,从而提供描述性的版本字符串

$ hg parent --template "{latesttag}+{latesttagdistance}-{node|short}\n"
v3.2+37-4b5d0d260e72
$ hg up 2.7
3316 files updated, 0 files merged, 379 files removed, 0 files unresolved
$ hg parent --template "{latesttag}+{latesttagdistance}-{node|short}\n"
v2.7.1+216-9619d21d8198

脚注


来源:https://github.com/python/peps/blob/main/peps/pep-0385.rst

最后修改时间:2023-09-09 17:39:29 GMT