Migrate to Mercurial VCS

From Post-Apocalyptic RPG wiki

Jump to: navigation, search

Infrastructure proposal.png This article covers an infrastructure proposal.

Infrastructure proposals are suggestions how to improve the project infrastructure; this also includes the code toolchain and tools for code documentation. Infrastructure proposals will be evaluated by the project management department and implemented down the line if they have been agreed upon.

This article proposes that PARPG migrate its codebase from Codesion's SVN hosting to a mercurial host.


Hosting Options

An acceptable mercurial host must meet the following criteria:

  • Supports Mercurial;
  • Free, and supports an unlimited number of developers;
  • Has a reasonable repository size limit (1~2 GB minimum);
  • Integrated tools for:
    • Bug tracking;
    • Milestone/progress reporting;


So far, Assembla is the only host we've found that meets all of our requirements. Assembla uses a modular framework with 20+ tools which can be added and removed from a workspace as needed, and many of these tools are specifically designed for agile development. Specifically, Assembla provides:

  • Free hosting for open-source projects;
  • Support for an unlimited number of svn, mercurial and git repositories all with integrated support with other Assembla tools;
  • An in-house bug tracker with an optional Trac frontend;
  • StandUp, which is an asynchronous messaging system designed to replace real-time SCRUM meetings;
  • Milestone tracking with integrated SCRUM backlog;
  • Continuous integration/build server hooks;

Assembla guarantees 1 year of free hosting no matter if they drop or change their free services, so worst case scenario we have only 1 year of free hosting with them. Given the limited number of free DVCS hosts that meet our requirements, I think this is reasonable. Most other hosts don't even guarantee their free service.

To collaborate with the PARPG team right now, you need to be invited to the project.

Look at https://www.assembla.com/spaces/parpg-core/ and ask for an invite please.

Mercurial versus SVN

Fixme.png Please help FIXME: Does this need any other sections?


Mercurial treats branching quite differently than most other VCS's, and in fact provides no less than 4 different kinds of branching. For an good overview of the various methods of branching in Mercurial I highly recommend Steve Losh's blog post on the subject.

In particular, it is important to note that unlike git and svn where you can choose which local branch should be pushed to the server Mercurial's default behavior is to push ALL branches to the server! This means that any branches you make locally (e.g. to work on new features) will be committed to the server and clutter up the main repository's history. It is thus very important that we carefully evaluate the different branching mechanisms that Mercurial offers.

The four methods of branching differ in whether and how the history of a branch is stored a) locally and b) when pushed to the main server. In summary, the types of branches in Mercurial are:

Named Branches
Created using hg branch <branchname>. Named branches split the revision history and keep track of every revision committed under the branch. Although it might be tempting to compare named branches to svn's branches, unlike svn Mercurial's named branches are permanently stored in history even after merging those changes back into the default branch (equivalent to svn's trunk).
Anonymous Branches (AKA Heads)
Created whenever a change (via a commit on an older revision, changes pulled from the server etc.) implicitly causes the history to branch. Heads are comparable to git's branching mechanism, except without the explicit naming (but see bookmarks below). Mercurial will warn you if you try to push changes that would result in creation of one or more new heads in the server's repository, as creation of new heads should generally be avoided on the server unless you have a really good reason for it.
Created using hg bookmarks <bookmark name>. Essentially, Mercurial bookmarks just add a convenient tag to an anonymous branch which you can use to refer to the head instead of its hash value or revision number. Bookmarked anonymous branches are essentially equivalent to git's branches.
The simplest and least intrusive method of branching is to simply clone the repository. The clone's history is completely independent of any other clone's history, and is the branching method most similar to svn's branching. Clones are also the only type of branching that is completely local - unless you push the clone upstream, it only exists on your system.


Fixme.png Please help FIXME: Finish evaluating different workflows

A DVCS is quite different from a centralized VCS like SVN, and requires a different workflow. Mercurial can support a wide variety of workflows so we will need to decide upon how we want to work with it.

Repository Structure

Although Mercurial does not require an explicit repository structure, it is a good idea to decide how we want the repository to look.

Steve Losh addressed the issue of repository structure in a series of articles on his blog. In summary, Losh identified and evaluated the following repository structures:

Branch As Needed
In this scheme, essentially the repository structure is not managed at all. Parallel changes are merged into the default branch as they appear, and named branches are created as needed. The problem with this approach is that it can quickly become difficult to tell when and where bugs were fixed, which versions are stable versus bleeding edge, etc.
Stable and Default
Two named branches exist in this scheme: the default branch, which contains all the latest bleeding-edge code, and the stable branch which contains all of the stable release code merged in from the default branch along with any minor bug fixes. All work on new features and major bug fixes occur on the default branch, while only minor bug fixes are applied to the stable branch and those minor bug fixes are immediately merged into the default branch. When we decide that the default branch has release-quality code we just merge it into stable and update any tags as necessary.

The "Stable and Default" repository structure has the advantage that it is very easy to understand and keep track of stable versus bleeding-edge revisions. It is therefore proposed that PARPG adopt this repository structure.

Local Changes

Mercurial has some somewhat unexpected behavior when it comes to tracking local changes with named branches (see #SVN versus Mercurial#Branching). As such, it is recommended that developers do not use named branches for tracking local changes.

Mercurial's bookmarks provide an alternative way of tacking local changes that don't directly affect history.

Fixme.png Please help FIXME: Describe how bookmarks could be used.

Another alternative is provided by a 3rd party extension to Mercurial called LocalBranch.

Fixme.png Please help FIXME: Describe what LocalBranch does.


Because merges in Mercurial are explicitly recorded in history (see #SVN versus Mercurial#Merging) merging often can result in a tangled history that is difficult to understand. See Jimmy Bogard's blog post on the subject for a thorough discussion on the subject.

Mercurial provides the Rebase extension which provides a git-like rebase mechanism.

Fixme.png Please help FIXME: Describe how rebasing is different from merging.

Given the pros and cons of merging versus rebasing, it is proposed that PARPG developers should rebase minor, iterative changes that are only a few commits in length and merge any changes that introduce significant new functionality or that are more than a few commits in length.


Another critical question we need to address is how we plan to represent major release versions of PARPG in the Mercurial repository. There are generally two different kinds of projects when it comes to releases: long-term support projects, and "progressive" projects.

Long-term Support Projects
These kind of projects are required to support earlier major versions, and thus may often add bugfixes and other minor changes to older revisions. For example, many code library projects are required to support older versions of the library and its API. In this case, creating a permanent branch for each major version of the library would make it easy to support the older versions by just appending a bugfix commit to the tip of the relevant release branch.
Progressive Projects
In contrast to long-term support projects, progressive projects do not have to maintain previous major versions of the project. If a bug arises the bugfix is simply applied to the head of development, and once testing has proved it to be stable the bugfix revision is tagged as the latest stable release. Most application and game projects fall into this category.

Although PARPG appears to fall into the "progressive project" category on the surface, it is actually a bit more complicated. Because we are an open source project we can expect outside developers to frequently fork our code and integrate it into their own projects. Indeed, one could argue that we are actually building a code library specific to PARPG but with applications elsewhere. Thus, we may find ourselves maintaining older versions of PARPG in use by outside developers.

Given these considerations, it is proposed that PARPG created a named branch for each and every major release version (e.g., release 1.0.0, 2.0.0, 3.0.0 etc.).

Fixme.png Please help FIXME: Expand on this

IRC commit notifications

Right now we're using cia.vc to report SVN commits in our IRC channel. The current solution relies on having a pseudo dev account set up that uses a trigger email address. Every time a new commit is checked in, email notifications will be send out to the trigger email address as well and the CIA bot will report the commit in the IRC channel.

This said: it seems that this approach does ONLY work for SVN repositories. There are a couple of potential alternatives to get the cia.vc bot working with 3rd party hg hosting as well:

Personal tools