peps/pep-0385/index.html

571 lines
34 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 385 Migrating from Subversion to Mercurial | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0385/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 385 Migrating from Subversion to Mercurial | peps.python.org'>
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0385/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="Python Enhancement Proposals (PEPs)">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 385</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 385 Migrating from Subversion to Mercurial</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Dirkjan Ochtman &lt;dirkjan&#32;&#97;t&#32;ochtman.nl&gt;,
Antoine Pitrou &lt;solipsis&#32;&#97;t&#32;pitrou.net&gt;,
Georg Brandl &lt;georg&#32;&#97;t&#32;python.org&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Normative PEP describing or proposing a change to a Python community process, workflow or governance">Process</abbr></dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even">25-May-2009</dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#motivation">Motivation</a></li>
<li><a class="reference internal" href="#timeline">Timeline</a></li>
<li><a class="reference internal" href="#transition-plan">Transition plan</a><ul>
<li><a class="reference internal" href="#branch-strategy">Branch strategy</a></li>
<li><a class="reference internal" href="#history-management">History management</a></li>
<li><a class="reference internal" href="#converting-tags">Converting tags</a></li>
<li><a class="reference internal" href="#author-map">Author map</a></li>
<li><a class="reference internal" href="#generating-hgignore">Generating .hgignore</a></li>
<li><a class="reference internal" href="#repository-size">Repository size</a></li>
<li><a class="reference internal" href="#other-repositories">Other repositories</a></li>
</ul>
</li>
<li><a class="reference internal" href="#infrastructure">Infrastructure</a><ul>
<li><a class="reference internal" href="#hg-ssh">hg-ssh</a></li>
<li><a class="reference internal" href="#hooks">Hooks</a></li>
<li><a class="reference internal" href="#end-of-line-conversions">End-of-line conversions</a></li>
<li><a class="reference internal" href="#hgwebdir">hgwebdir</a></li>
<li><a class="reference internal" href="#roundup">roundup</a></li>
</ul>
</li>
<li><a class="reference internal" href="#after-migration">After migration</a><ul>
<li><a class="reference internal" href="#where-to-get-code">Where to get code</a></li>
<li><a class="reference internal" href="#python-specific-documentation">Python-specific documentation</a></li>
<li><a class="reference internal" href="#proposed-workflow">Proposed workflow</a></li>
<li><a class="reference internal" href="#the-future-of-subversion">The future of Subversion</a></li>
<li><a class="reference internal" href="#build-identification">Build identification</a></li>
</ul>
</li>
<li><a class="reference internal" href="#footnotes">Footnotes</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="motivation">
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
<p>After having decided to switch to the Mercurial DVCS, the actual
migration still has to be performed. In the case of an important
piece of infrastructure like the version control system for a large,
distributed project like Python, this is a significant effort. This
PEP is an attempt to describe the steps that must be taken for further
discussion. Its somewhat similar to <a class="pep reference internal" href="../pep-0347/" title="PEP 347 Migrating the Python CVS to Subversion">PEP 347</a>, which discussed the
migration to SVN.</p>
<p>To make the most of hg, we would like to make a high-fidelity
conversion, such that (a) as much of the svn metadata as possible is
retained, and (b) all metadata is converted to formats that are common
in Mercurial. This way, tools written for Mercurial can be optimally
used. In order to do this, we want to use the <a class="reference external" href="http://bitbucket.org/durin42/hgsubversion/">hgsubversion</a>
software to do an initial conversion. This hg extension is focused on
providing high-quality conversion from Subversion to Mercurial for use
in two-way correspondence, meaning it doesnt throw away as much
available metadata as other solutions.</p>
<p>Such a conversion also seems like a good time to reconsider the
contents of the repository and determine if some things are still
valuable. In this spirit, the following sections also propose
discarding some of the older metadata.</p>
</section>
<section id="timeline">
<h2><a class="toc-backref" href="#timeline" role="doc-backlink">Timeline</a></h2>
<p>The current schedule for conversion milestones:</p>
<ul>
<li>2011-02-24: availability of a test repo at hg.python.org<p>Test commits will be allowed (and encouraged) from all committers to
the Subversion repository. The test repository and all test commits
will be removed once the final conversion is done. The server-side
hooks will be installed for the test repository, in order to test
buildbot, diff-email and whitespace checking integration.</p>
</li>
<li>2011-03-05: final conversion (tentative)<p>Commits to the Subversion branches now maintained in Mercurial will
be blocked. Developers should refrain from pushing to the Mercurial
repositories until all infrastructure is ensured to work after their
switch over to the new repository.</p>
</li>
</ul>
</section>
<section id="transition-plan">
<h2><a class="toc-backref" href="#transition-plan" role="doc-backlink">Transition plan</a></h2>
<section id="branch-strategy">
<h3><a class="toc-backref" href="#branch-strategy" role="doc-backlink">Branch strategy</a></h3>
<p>Mercurial has two basic ways of using branches: cloned branches, where
each branch is kept in a separate repository, and named branches,
where each revision keeps metadata to note on which branch it belongs.
The former makes it easier to distinguish branches, at the expense of
requiring more disk space on the client. The latter makes it a little
easier to switch between branches, but all branch names are a
persistent part of history. <a class="footnote-reference brackets" href="#id3" id="id1">[1]</a></p>
<p>Differences between named branches and cloned branches:</p>
<ul class="simple">
<li>Tags in a different (maintenance) clone arent available in the
local clone</li>
<li>Clones with named branches will be larger, since they contain more
data</li>
</ul>
<p>We propose to use named branches for release branches and adopt cloned
branches for feature branches.</p>
</section>
<section id="history-management">
<h3><a class="toc-backref" href="#history-management" role="doc-backlink">History management</a></h3>
<p>In order to minimize the loss of information due to the conversion, we
propose to provide several repositories as a conversion result:</p>
<ul>
<li>A repository trimmed to the mainline trunk (and py3k), as well as
past and present maintenance branches this is called the
“working” repo and is where development continues. This repository has
all the history needed for development work, including annotating
source files with changes back up to 1990 and other common history-digging
operations.<p>The <code class="docutils literal notranslate"><span class="pre">default</span></code> branch in that repo is what is known as <code class="docutils literal notranslate"><span class="pre">py3k</span></code> in
Subversion, while the Subversion trunk lives on with the branch name
<code class="docutils literal notranslate"><span class="pre">legacy-trunk</span></code>; however in Mercurial this branch will be closed.
Release branches are named after their major.minor version, e.g. <code class="docutils literal notranslate"><span class="pre">3.2</span></code>.</p>
</li>
<li>A repository with the full, unedited conversion of the Subversion
repository (actually, its /python subdirectory) this is called
the “historic” or “archive” repo and will be offered as a read-only
resource. <a class="footnote-reference brackets" href="#id4" id="id2">[2]</a></li>
<li>One more repository per active feature branch; “active” means that
at least one core developer asks for the branch to be provided. Each
such repository will contain both the feature branch and all ancestor
changesets from mainline (coming from <code class="docutils literal notranslate"><span class="pre">trunk</span></code> and/or <code class="docutils literal notranslate"><span class="pre">py3k</span></code> in SVN).</li>
</ul>
<p>Since all branches are present in the historic repo, they can later be
extracted as separate repositories at any time should it prove to be
necessary.</p>
<p>The final revision map between SVN revision numbers, Mercurial changesets
and SVN branch names will be made available in a file stored in the <code class="docutils literal notranslate"><span class="pre">Misc</span></code>
directory. Its format is as following:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="mi">88483</span> <span class="n">e65daae6cf4499a0863cb7645109a4798c28d83e</span> <span class="n">issue10276</span><span class="o">-</span><span class="n">snowleopard</span>
<span class="mi">88484</span> <span class="mi">835</span><span class="n">cb57abffeceaff0d85c2a3aa0625458dd3e31</span> <span class="n">py3k</span>
<span class="mi">88485</span> <span class="n">d880f9d8492f597a030772c7485a34aadb6c4ece</span> <span class="n">release32</span><span class="o">-</span><span class="n">maint</span>
<span class="mi">88486</span> <span class="mi">0</span><span class="n">c431b8c22f5dbeb591414c154acb7890c1809df</span> <span class="n">py3k</span>
<span class="mi">88487</span> <span class="mi">82</span><span class="n">cda1f21396bbd10db8083ea20146d296cb630b</span> <span class="n">release32</span><span class="o">-</span><span class="n">maint</span>
<span class="mi">88488</span> <span class="mi">8174</span><span class="n">d00d07972d6f109ed57efca8273a4d59302c</span> <span class="n">release27</span><span class="o">-</span><span class="n">maint</span>
<span class="p">[</span><span class="o">...</span><span class="p">]</span>
</pre></div>
</div>
</section>
<section id="converting-tags">
<h3><a class="toc-backref" href="#converting-tags" role="doc-backlink">Converting tags</a></h3>
<p>The SVN tags directory contains a lot of old stuff. Some of these are
not, in fact, full tags, but contain only a smaller subset of the
repository. All release tags will be kept; other tags will be
included based on requests from the developer community. We propose
to make the tag naming scheme consistent, in this style: <code class="docutils literal notranslate"><span class="pre">v3.2.1a2</span></code>.</p>
</section>
<section id="author-map">
<h3><a class="toc-backref" href="#author-map" role="doc-backlink">Author map</a></h3>
<p>In order to provide user names the way they are common in hg (in the
First Last &lt;<a class="reference external" href="mailto:user&#37;&#52;&#48;example&#46;org">user<span>&#64;</span>example<span>&#46;</span>org</a>&gt; format), we need an author map to map
cvs and svn user names to real names and their email addresses. We
have a complete version of such a map in the migration tools
repository (not publicly accessible to avoid leaking addresses to
harvesters). The email addresses in it might be out of date; thats
bound to happen, although it would be nice to try and have as many
people as possible review it for addresses that are out of date. The
current version also still seems to contain some encoding problems.</p>
</section>
<section id="generating-hgignore">
<h3><a class="toc-backref" href="#generating-hgignore" role="doc-backlink">Generating .hgignore</a></h3>
<p>The .hgignore file can be used in Mercurial repositories to help
ignore files that are not eligible for version control. It does this
by employing several possible forms of pattern matching. The current
Python repository already includes a rudimentary .hgignore file to
help with using the hg mirrors.</p>
<p>Since the current Python repository already includes a .hgignore file
(for use with hg mirrors), well just use that. Generating full
history of the file was debated but deemed impractical (because its
relatively hard with fairly little gain, since ignoring is less
important for older revisions).</p>
</section>
<section id="repository-size">
<h3><a class="toc-backref" href="#repository-size" role="doc-backlink">Repository size</a></h3>
<p>A bare conversion result of the current Python repository weighs 1.9
GB; although this is smaller than the Subversion repository (2.7 GB)
it is not feasible.</p>
<p>The size becomes more manageable by the trimming applied to the
working repository, and by a process called “revlog reordering” that
optimizes the layout of internal Mercurial storage very efficiently.</p>
<p>After all optimizations done, the size of the working repository is
around 180 MB on disk. The amount of data transferred over the
network when cloning is estimated to be around 80 MB.</p>
</section>
<section id="other-repositories">
<h3><a class="toc-backref" href="#other-repositories" role="doc-backlink">Other repositories</a></h3>
<p>There are a number of other projects hosted in svn.python.orgs
“projects” repository. The “peps” directory will be converted along
with the main Python one. Richard Tew has indicated that hed like the
Stackless repository to also be converted. What other projects in the
svn.python.org repository should be converted?</p>
<p>Theres now an initial stab at converting the Jython repository. The
current tip of hgsubversion unfortunately fails at some point.
Pending investigation.</p>
<p>Other repositories that would like to converted to Mercurial can
announce themselves to me after the main Python migration is done, and
Ill take care of their needs.</p>
</section>
</section>
<section id="infrastructure">
<h2><a class="toc-backref" href="#infrastructure" role="doc-backlink">Infrastructure</a></h2>
<section id="hg-ssh">
<h3><a class="toc-backref" href="#hg-ssh" role="doc-backlink">hg-ssh</a></h3>
<p>Developers should access the repositories through ssh, similar to the
current setup. Public keys can be used to grant people access to a
shared hg&#64; account. A hgwebdir instance also has been set up at
<code class="docutils literal notranslate"><span class="pre">hg.python.org</span></code> for easy browsing and read-only access. It is
configured so that developers can trivially start new clones (for
longer-term features that profit from development in a separate
repository).</p>
<p>Also, direct creation of public repositories is allowed for core developers,
although it is not yet decided which naming scheme will be enforced:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ hg init ssh://hg@hg.python.org/sandbox/mywork
repo created, public URL is http://hg.python.org/sandbox/mywork
</pre></div>
</div>
</section>
<section id="hooks">
<h3><a class="toc-backref" href="#hooks" role="doc-backlink">Hooks</a></h3>
<p>A number of hooks is currently in use. The hg equivalents for these
should be developed and deployed. The following hooks are being used:</p>
<ul class="simple">
<li>check whitespace: a hook to reject commits in case the whitespace
doesnt match the rules for the Python codebase. In a changegroup,
only the tip is checked (this allows cleanup commits for changes
pulled from third-party repos). We can also offer a whitespace hook
for use with client-side repositories that people can use; it could
either warn about whitespace issues and/or truncate trailing
whitespace from changed lines.</li>
<li>push mails: Emails will include diffs for each changeset pushed
to the public repository, including the username which pushed the
changesets (this is not necessarily the same as the author recorded
in the changesets).</li>
<li>buildbots: the python.org build master will be notified of each changeset
pushed to the <code class="docutils literal notranslate"><span class="pre">cpython</span></code> repository, and will trigger an appropriate build
on every build slave for the branch in which the changeset occurs.</li>
</ul>
<p>The <a class="reference external" href="http://hg.python.org/hooks/">hooks repository</a> contains ports of these server-side hooks to
Mercurial, as well as a couple additional ones:</p>
<ul class="simple">
<li>check branch heads: a hook to reject pushes which create a new head on
an existing branch. The pusher then has to merge the excess heads
and try pushing again.</li>
<li>check branches: a hook to reject all changesets not on an allowed named
branch. This hooks whitelist will have to be updated when we want to
create new maintenance branches.</li>
<li>check line endings: a hook, based on the <a class="reference external" href="http://mercurial.selenic.com/wiki/EolExtension">eol extension</a>, to reject all
changesets committing files with the wrong line endings. The commits then
have to be stripped and redone, possibly with the <a class="reference external" href="http://mercurial.selenic.com/wiki/EolExtension">eol extension</a> enabled
on the comitters computer.</li>
</ul>
<p>One additional hook could be beneficial:</p>
<ul class="simple">
<li>check contributors: in the current setup, all changesets bear the
username of committers, who must have signed the contributor
agreement. We might want to use a hook to check if the committer is
a contributor if we keep a list of registered contributors. Then,
the hook might warn users that push a group of revisions containing
changesets from unknown contributors.</li>
</ul>
</section>
<section id="end-of-line-conversions">
<h3><a class="toc-backref" href="#end-of-line-conversions" role="doc-backlink">End-of-line conversions</a></h3>
<p>Discussion about the lack of end-of-line conversion support in
Mercurial, which was provided initially by the <a class="reference external" href="http://mercurial.selenic.com/wiki/Win32TextExtension">win32text extension</a>,
led to the development of the new <a class="reference external" href="http://mercurial.selenic.com/wiki/EolExtension">eol extension</a> that supports a
versioned management of line-ending conventions on a file-by-file
basis, akin to Subversions <code class="docutils literal notranslate"><span class="pre">svn:eol-style</span></code> properties. This
information is kept in a versioned file called <code class="docutils literal notranslate"><span class="pre">.hgeol</span></code>, and such a
file has already been checked into the Subversion repository.</p>
<p>A hook also exists on the server side to reject any changeset
introducing inconsistent newline data (see above).</p>
</section>
<section id="hgwebdir">
<h3><a class="toc-backref" href="#hgwebdir" role="doc-backlink">hgwebdir</a></h3>
<p>A more or less stock hgwebdir installation should be set up. We might
want to come up with a style to match the Python website.</p>
<p>A small WSGI application has been written that can look up
Subversion revisions and redirect to the appropriate hgweb page for
the given changeset, regardless in which repository the converted
revision ended up (since one big Subversion repository is converted
into several Mercurial repositories). It can also look up Mercurial
changesets by their hexadecimal ID.</p>
</section>
<section id="roundup">
<h3><a class="toc-backref" href="#roundup" role="doc-backlink">roundup</a></h3>
<p>By pointing Roundup to the URL of the lookup script mentioned above,
links to SVN revisions will continue to work, and links to Mercurial
changesets can be created as well, without having to give repository
<em>and</em> changeset ID.</p>
</section>
</section>
<section id="after-migration">
<h2><a class="toc-backref" href="#after-migration" role="doc-backlink">After migration</a></h2>
<section id="where-to-get-code">
<h3><a class="toc-backref" href="#where-to-get-code" role="doc-backlink">Where to get code</a></h3>
<p>After migration, the hgwebdir will live at hg.python.org. This is an
accepted standard for many organizations, and an easy parallel to
svn.python.org. The working repo might live at
<a class="reference external" href="http://hg.python.org/cpython/">http://hg.python.org/cpython/</a>, for example, with the archive repo at
<a class="reference external" href="http://hg.python.org/cpython-archive/">http://hg.python.org/cpython-archive/</a>. For write access, developers
will have to use ssh, which could be <a class="reference external" href="ssh://hg&#64;hg.python.org/cpython/">ssh://hg&#64;hg.python.org/cpython/</a>.</p>
<p>code.python.org was also proposed as the hostname. We think that
using the VCS name in the hostname is good because it prevents
confusion: it should be clear that you cant use svn or bzr for
hg.python.org.</p>
<p>hgwebdir can already provide tarballs for every changeset. This
obviates the need for daily snapshots; we can just point users to
tip.tar.gz instead, meaning they will get the latest. If desired, we
could even use buildbot results to point to the last good changeset.</p>
</section>
<section id="python-specific-documentation">
<h3><a class="toc-backref" href="#python-specific-documentation" role="doc-backlink">Python-specific documentation</a></h3>
<p>hg comes with good built-in documentation (available through hg help)
and a <a class="reference external" href="http://mercurial.selenic.com/wiki/">wiki</a> thats full of useful information and recipes, not to
mention a popular <a class="reference external" href="http://hgbook.red-bean.com/">book</a> (readable online).</p>
<p>In addition to that, the recently overhauled <a class="reference external" href="http://docs.python.org/devguide/">Python Developers
Guide</a> already has a branch with instructions for Mercurial instead
of Subversion; an online <a class="reference external" href="http://potrou.net/hgdevguide/">build of this branch</a> is also available.</p>
</section>
<section id="proposed-workflow">
<h3><a class="toc-backref" href="#proposed-workflow" role="doc-backlink">Proposed workflow</a></h3>
<p>We propose two workflows for the migration of patches between several
branches.</p>
<p>For migration within 2.x or 3.x branches, we propose a patch always
gets committed to the oldest branch where it applies first. Then, the
resulting changeset can be merged using hg merge to all newer branches
within that series (2.x or 3.x). If it does not apply as-is to the
newer branch, hg revert can be used to easily revert to the
new-branch-native head, patch in some alternative version of the patch
(or none, if its not applicable), then commit the merge. The premise
here is that all changesets from an older branch within the series are
eventually merged to all newer branches within the series.</p>
<p>The upshot is that this provides for the most painless merging
procedure. This means that in the general case, people have to think
about the oldest branch to which the patch should be applied before
actually applying it. Usually, that is one of only two branches: the
latest maintenance branch and the trunk, except for security fixes
applicable to older branches in security-fix-only mode.</p>
<p>For merging bug fixes from the 3.x to the 2.7 maintenance branch (2.6
and 2.5 are in security-fix-only mode and their maintenance will
continue in the Subversion repository), changesets should be
transplanted (not merged) in some other way. The transplant
extension, import/export and bundle/unbundle work equally well here.</p>
<p>Choosing this approach allows 3.x not to carry all of the 2.x
history-since-it-was-branched, meaning the clone is not as big and the
merges not as complicated.</p>
</section>
<section id="the-future-of-subversion">
<h3><a class="toc-backref" href="#the-future-of-subversion" role="doc-backlink">The future of Subversion</a></h3>
<p>What happens to the Subversion repositories after the migration?
Since the svn server contains a bunch of repositories, not just the
CPython one, it will probably live on for a bit as not every project
may want to migrate or it takes longer for other projects to migrate.
To prevent people from staying behind, we may want to move migrated
projects from the repository to a new, read-only repository with a new
name.</p>
</section>
<section id="build-identification">
<h3><a class="toc-backref" href="#build-identification" role="doc-backlink">Build identification</a></h3>
<p>Python currently provides the sys.subversion tuple to allow Python
code to find out exactly what version of Python its running against.
The current version looks something like this:</p>
<ul class="simple">
<li>(CPython, tags/r262, 71600)</li>
<li>(CPython, trunk, 73128M)</li>
</ul>
<p>Another value is returned from Py_GetBuildInfo() in the C API, and
available to Python code as part of sys.version:</p>
<ul class="simple">
<li>r262:71600, Jun 2 2009, 09:58:33</li>
<li>trunk:73128M, Jun 2 2009, 01:24:14</li>
</ul>
<p>I propose that the revision identifier will be the short version of
hgs revision hash, for example dd3ebf81af43, augmented with +
(instead of M) if the working directory from which it was built was
modified. This mirrors the output of the hg id command, which is
intended for this kind of usage. The sys.subversion value will also
be renamed to sys.mercurial to reflect the change in VCS.</p>
<p>For the tag/branch identifier, I propose that hg will check for tags
on the currently checked out revision, use the tag if there is one
(tip doesnt count), and uses the branch name otherwise.
sys.subversion becomes</p>
<ul class="simple">
<li>(CPython, v2.6.2, dd3ebf81af43)</li>
<li>(CPython, default, af694c6a888c+)</li>
</ul>
<p>and the build info string becomes</p>
<ul class="simple">
<li>v2.6.2:dd3ebf81af43, Jun 2 2009, 09:58:33</li>
<li>default:af694c6a888c+, Jun 2 2009, 01:24:14</li>
</ul>
<p>This reflects that the default branch in hg is called default
instead of Subversions trunk, and reflects the proposed new tag
format.</p>
<p>Mercurial also allows to find out the latest tag and the number of
changesets separating the current changeset from that tag, allowing for
a descriptive version string:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ hg parent --template &quot;{latesttag}+{latesttagdistance}-{node|short}\n&quot;
v3.2+37-4b5d0d260e72
$ hg up 2.7
3316 files updated, 0 files merged, 379 files removed, 0 files unresolved
$ hg parent --template &quot;{latesttag}+{latesttagdistance}-{node|short}\n&quot;
v2.7.1+216-9619d21d8198
</pre></div>
</div>
</section>
</section>
<section id="footnotes">
<h2><a class="toc-backref" href="#footnotes" role="doc-backlink">Footnotes</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id3" role="doc-footnote">
<dt class="label" id="id3">[<a href="#id1">1</a>]</dt>
<dd>The Mercurial book discourages the use of named branches, but
it is, in this respect, somewhat outdated. Named branches have
gotten much easier to use since that comment was written, due to
improvements in hg.</aside>
<aside class="footnote brackets" id="id4" role="doc-footnote">
<dt class="label" id="id4">[<a href="#id2">2</a>]</dt>
<dd>Since the initial working repo is a subset of the archive repo,
it would also be feasible to pull changes from the working repo
into the archive repo periodically.</aside>
</aside>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0385.rst">https://github.com/python/peps/blob/main/peps/pep-0385.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0385.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#motivation">Motivation</a></li>
<li><a class="reference internal" href="#timeline">Timeline</a></li>
<li><a class="reference internal" href="#transition-plan">Transition plan</a><ul>
<li><a class="reference internal" href="#branch-strategy">Branch strategy</a></li>
<li><a class="reference internal" href="#history-management">History management</a></li>
<li><a class="reference internal" href="#converting-tags">Converting tags</a></li>
<li><a class="reference internal" href="#author-map">Author map</a></li>
<li><a class="reference internal" href="#generating-hgignore">Generating .hgignore</a></li>
<li><a class="reference internal" href="#repository-size">Repository size</a></li>
<li><a class="reference internal" href="#other-repositories">Other repositories</a></li>
</ul>
</li>
<li><a class="reference internal" href="#infrastructure">Infrastructure</a><ul>
<li><a class="reference internal" href="#hg-ssh">hg-ssh</a></li>
<li><a class="reference internal" href="#hooks">Hooks</a></li>
<li><a class="reference internal" href="#end-of-line-conversions">End-of-line conversions</a></li>
<li><a class="reference internal" href="#hgwebdir">hgwebdir</a></li>
<li><a class="reference internal" href="#roundup">roundup</a></li>
</ul>
</li>
<li><a class="reference internal" href="#after-migration">After migration</a><ul>
<li><a class="reference internal" href="#where-to-get-code">Where to get code</a></li>
<li><a class="reference internal" href="#python-specific-documentation">Python-specific documentation</a></li>
<li><a class="reference internal" href="#proposed-workflow">Proposed workflow</a></li>
<li><a class="reference internal" href="#the-future-of-subversion">The future of Subversion</a></li>
<li><a class="reference internal" href="#build-identification">Build identification</a></li>
</ul>
</li>
<li><a class="reference internal" href="#footnotes">Footnotes</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0385.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>