mirror of https://github.com/python/peps
571 lines
34 KiB
HTML
571 lines
34 KiB
HTML
|
||
<!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> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </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 <dirkjan at ochtman.nl>,
|
||
Antoine Pitrou <solipsis at pitrou.net>,
|
||
Georg Brandl <georg at python.org></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. It’s 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 doesn’t 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 aren’t 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 <<a class="reference external" href="mailto:user%40example.org">user<span>@</span>example<span>.</span>org</a>>’ 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; that’s
|
||
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), we’ll just use that. Generating full
|
||
history of the file was debated but deemed impractical (because it’s
|
||
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.org’s
|
||
“projects” repository. The “peps” directory will be converted along
|
||
with the main Python one. Richard Tew has indicated that he’d like the
|
||
Stackless repository to also be converted. What other projects in the
|
||
svn.python.org repository should be converted?</p>
|
||
<p>There’s 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
|
||
I’ll 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@ 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
|
||
doesn’t 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 hook’s 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 comitter’s 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 Subversion’s <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@hg.python.org/cpython/">ssh://hg@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 can’t 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> that’s 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 Developer’s
|
||
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 it’s 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 it’s 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
|
||
hg’s 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’ doesn’t 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 Subversion’s ‘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 "{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
|
||
</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> |