Mercurial on TextDrive, Part I

The TextDrive theme continues! Trac-hacks.org has been down for a couple of weeks — apparently the maintainer went out of town shortly before the server tanked — so I’m stalling on Part II of my Trac on TextDrive article. Sorry! Plug-in installation is the focus of the article, so it would be rather frustrating to try to follow along when most of the resources are unavailable…

In the mean time, I’ve been trying out Mercurial and really digging it. Mercurial is a distributed version control system, and we’ll talk a little about why you may want such a thing. Also, it’s written (mostly) in Python, and has a very functional Trac plug-in (that incidentally is not hosted on Trac-hacks currently!), so it seems to fit pretty well into our current theme.

Bill de hOra has written a couple of useful articles on Mercurial set-up that are specific to TextDrive, but they’re “terse” by his own words, and the user-local Python environment that we set up earlier affords us a more straightforward procedure. I’ll also try to pick up where Bill left off by briefly covering Mercurial set-up and use with SSH.

But what is this all about, really? There’s been a lot of chatter recently on the rise of distributed VCSes like Bazaar, git, darcs, etc., and I’m not going to go into detail about opting for one tool over another (Wikipedia has a big comparison matrix if you’re looking for a place to start your own research). Rather than sweating the minutiae that separate these tools, readers here would probably be better served by some discussion of why one may want a distributed SCM in the first place. While I haven’t explicitly covered the use of a VCS in the past, the depth of my Trac articles probably appeals more to the beginner than the seasoned (read: impatient) version control user, and someone just starting with Subversion may wonder why he or she should think about throwing it out and starting over. Read on for more, or you can just jump ahead to the set-up details if you like.

Contents

An Overview of the Distributed Model

First off, what’s wrong with Subversion? Well, it is by no means a terrible system, and as an answer to CVS it was an undisputed blessing. Many of its shortcomings become apparent in projects with numerous developers committing, or when you are the lucky one tasked with resolving conflicts. Still, I believe that distributed systems also offer advantages for smaller teams and even individuals, and I’ll try to make light of them.

The preeminent feature of a DVCS, as the name implies, is that every working copy has a complete copy of the project’s revision history — in reality, a “working copy” is no different from the “canonical” repository. This means that team members can easily work offline, and as a bonus you’ll likely have multiple isolated back-ups of your full history. Of course this is no substitute for a proper back-up scheme, but it also means that any unavailability of your central VCS server doesn’t predicate a grinding halt in a team’s productivity.

For project maintainers in particular, as I alluded to previously, most of the distributed systems have significantly better branch and merge capabilities, and Mercurial is fully ready for 3-way merge tools. Branching in Subversion is particularly limited. There are also some very sophisticated extensions, such as Mercurial Queues, which gives maintainers a powerful means of juggling patches. These things are really beyond the scope of this article, though.

I haven’t rigorously evaluated the competition — I’ve chosen Mercurial based on others’ accounts, speed and convenience, and generally liking the “feel” of the commands and usage patterns after trying it for a bit. It doesn’t hurt that there are excellent resources available, like Bryan O’Sullivan’s Google Tech Talk, and his comprehensive and free reference book. For icing on the cake, there’s a very good TextMate Bundle, useful tools like hgsvn, and a high level of extensibility. You may find that another DVCS works better for you, but nonetheless the principles here should apply.

Value and Working Practices

To me, the most compelling reasons for individuals and small teams to try Mercurial are speed, flexibility, and a more natural workflow that encourages experimentation and frequent commits. It’s possible to use Mercurial in almost exactly the same way as you would use Subversion, but some acknowledged best practices suggest another approach something like this:

  1. clone a copy from the “authoritative” repository, and designate it as a “pristine” branch for regularly pulling the latest updates.
  2. For each new feature or bug fix that you want to work on, create a named clone from your local pristine branch and do your work there. These operations are very fast and inexpensive with Mercurial, especially locally, making it easy for you to explore several paths to a solution and commit often without worrying about polluting the revision history for everyone else.
  3. Once you arrive at a workable solution, create an “outgoing” clone from your pristine branch, and merge your improvements there. It should be noted here that a commit in Mercurial is a local operation, and you will push updates back to the authoritative repo once you’ve got working code, or simply export a patch for emailing.

The official Mercurial wiki has more info on common working practices. I’ll offer a very brief run-through of common commands after the installation procedures, along with a link to the official tutorial for more detail. Mercurial’s command set is small and intuitive, and it is thoroughly self-documenting, as we’ll see shortly. Many of the commands parallel their svn counterparts, so you can learn quickly.

The last note that I’ll make about the value of Mercurial for a small team is to point out the facilities for ad-hoc collaboration. The distribution contains a built-in web server, and a user can publish his repository on demand with one quick command (Mercurial supports push and pull across SSH or HTTP/HTTP">HTTPS). I can imagine this being very useful and flexible for groups practicing agile development methods, pair programming, or impromptu sprints at user group meetings or conferences.

Alright, enough filibustering, let’s take some action already!

Getting It Working

Once again, assuming that you followed my instructions for setting up a user-local Python environment, then installing Mercurial is a cakewalk:

$ easy_install mercurial

This should be run over a shell connection to your shared host. Of course, you’ll want Mercurial installed on your own machine to work with it. First, get Python if you don’t already have it. The steps for installation will differ depending on your platform. Once you have Python up and running, you can grab easy_install and just use the same command as above. Alternatively, you can install from source, which should be a simple build. The easy_install method may not install the man pages, but otherwise it is plainly simple to install and upgrade (via easy_install -U mercurial). You’ll probably find that all the help you need is built in anyhow. Finally, if you have any trouble, check the official Mercurial tutorial, which gives detailed installation instructions.

Creating Your First Repository

We’ll soon be serving up your repo(s) on the web (that’s why you’re reading this, right?), but we need a repo first! That’s pretty easy. You can start with an empty directory and add to it, or if you have a project you wish to use you can turn an existing directory into a repository. From your home directory:

$ mkdir hg; cd hg
# if you have a project already:
$ cp -R your/project/dirname .  # note the dot!
$ hg init dirname
# or if you want to start with a clean slate, just:
$ hg init spiffyname

The ‘spiffyname’ dir would be created for you if it didn’t already exist. ‘hg‘, the atomic symbol for Mercury, is the Mercurial command-line tool. We’re intentionally creating the hg directory outside of your web/public so that there’s no danger of someone snooping it out should you elect not to serve your repository via HTTP. You can have multiple repositories, and we’ll see how to add files soon.

Before we go any further, take a second to add your name and email address to Mercurial’s config file:

$ nano ~/.hgrc
... add the following ...
[ui]
username = Your Name <your [at] email [dot] com>
... close and save with CTRL-O, CTRL-X ...

This is the customary format, but use what you’d like. This will identify you in all of Mercurial’s records. Your email address will automatically appear obfuscated to users who aren’t logged in, to protect you from spam.

Serving With hgwebdir.cgi

hgwebdir is a CGI script — included with the source distribution of Mercurial — that allows you to serve one or multiple repositories over HTTP/HTTPS. It provides a simple web interface to browse the source code and changesets, and also allows you to push and pull revisions. You only need to follow these steps if you wish to allow others to have access to the repository; if you want a private set up, just use SSH as detailed in the next subsection.

WARNING! The steps I’m going to show you will result in an insecure repository, in that your transactions with the server will cross the wires in clear text. I don’t have an SSL certificate at TextDrive, so if you do, feel free to skip the step we’ll take to explicitly allow plain HTTP. More info is here. This doesn’t mean that you can’t restrict access for viewing and altering the repo on the web, but it does mean that you shouldn’t use plain HTTP if you intend to work with sensitive data. If your project is open source, this probably doesn’t matter at all.

Since we installed Mercurial as an egg, we need to fetch the CGI script, and make a directory for it in your web document root:

$ cd ~/web/public
$ mkdir hg; cd hg
$ wget http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi

You can really name this directory whatever you want. Unless you’ve changed defaults at TextDrive, this will be accessible at both http://yourdomain.com/hg and http://hg.yourdomain.com when configuration is complete. Next, we need to create and edit a few files and assure that the script file is executable.


 # First edit the CGI and set an absolute path to your python executable:

$ nano hgwebdir.cgi … replace top line with #!/users/home//python/bin/python … … CTRL-O, CTRL-X to save and exit … # make the file executable: $ chmod a+x hgwebdir.cgi # now we’ll create a config file $ nano hgweb.config … enter the following: … [paths] spiffyname = /users/home/<you>/hg/spiffyname … CTRL-O, CTRL-X to save and exit … # finally, a local .htaccess file for custom Apache options: $ nano .htaccess … enter the following: … Options +ExecCGI RewriteEngine On RewriteBase /hg RewriteRule ^$ hgwebdir.cgi [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) hgwebdir.cgi/$1 [QSA,L] AuthType Digest AuthName “yourdomain.com” AuthDigestDomain /hg/ AuthDigestProvider file AuthUserFile /users/home//etc/hg.digest.passwd <LimitExcept GET> Require valid-user </LimitExcept> … CTRL-O, CTRL-X to save and exit …

In the hgweb.config file, whatever you enter on the left will be shown in the URL, i.e. http://yourdomain.com/hg/spiffyname. The right side of course must point to a valid repository. If you have multiple repos, enter them all here in the same fashion. The .htaccess file tells the Apache to allow CGI scripts in the current directory, does some mod_rewrite tricks to give you nicer URLs, and defines some authentication settings. <LimitExcept GET> allows browsing without a password, but will prevent unauthorized push attempts. See the Apache docs to customize this further. Now we just need to create the password file referenced there:

$ htdigest -c /users/home/<you>/etc/hg.digest.passwd yourdomain.tld username

You’ll be prompted for a password. Omit the -c switch for future calls, such as adding and updating users.

One more file to edit and things should be ready to go. Use nano again to open ~/hg/<your_repo>/.hg/hgrc and add the following:

[web]
allow_push = user1, user2
push_ssl = false
contact = Your Name <your [at] email [dot] com>
description = Describe your project.
name = Site Title
style = gitweb

Note: the push_ssl setting is what makes this set up insecure, but without it you must have an SSL certificate or only use SSH. You can use an asterisk (*) if you would like to give push access to everyone who has a password configured. Also, it appears that an email address in the contact field here does not get obfuscated on the site. Finally, the gitweb style is optional — it’s a clone of the git DVCS’ web interface, and in my opinion looks much better than Mercurial’s default.

Mercurial gitweb crop
The gitweb style.

That should do it! Fire up your browser, point it it http://yourdomain.com/hg/ and you should see a list of your repositories. In the next part, I’ll show you the basic commands for working with hg, including how to push and pull over HTTP.

Until Next Time…

Alright, this is pretty lengthy already, so I’m going to save the usage summary, SSH access, the TracMercurial plug-in and the Mercurial TextMate bundle for a second installment. We’ll also enable a handy feature that makes tarballs of the tip of your repository available as a link all the time. Until then, check out the official tutorial!

error while installing mercurial

Hi,

Great posts on setting up Trac & Mercurial on TextDrive. I followed your part one of installing Trac. I stopped and started installing Mercurial. I got the error below when I issued the command “easy_install mercurial”

Searching for mercurial
Reading http://pypi.python.org/simple/mercurial/
Couldn’t find index page for ‘mercurial’ (maybe misspelled?)
Scanning index of all packages (this may take a while)
Reading http://pypi.python.org/simple/
Reading http://pypi.python.org/simple/Mercurial/
Reading http://www.selenic.com/mercurial
Best match: mercurial 0.9.5
Downloading http://www.selenic.com/mercurial/release/mercurial-0.9.5.tar.gz
Processing mercurial-0.9.5.tar.gz
Running mercurial-0.9.5/setup.py -q bdist_egg —dist-dir /tmp/easy_install-b9bT5L/mercurial-0.9.5/egg-dist-tmp-CtDiuN
Traceback (most recent call last):

[…output snipped… – Ed.]

Awkward,Spinning aneth

Awkward,Spinning aneth considérant déshabiller à partir de certains je veux hacker un compte facebook gratuitement.
planter au lieu de jouer pirater un compte facebook commentcamarche.

Hello, Apologies for

Hello,

Apologies for editing your comment — the traceback was a bit ugly and was freaking out Textile a little ;-)

I’m glad you brought this to attention, as it deserves note: a new version of Mercurial has just been released (0.9.5), and is known to not play nice with easy_install. There’s a bug report listed here.

The easiest way around this is just to force installation of the prior version:

$ easy_install mercurial==0.9.4

Or if there’s something you must have in the new version, you’ll have to download and build manually. Just see the Mercurial site for instructions in that case.

Update

Mercurial has reached 1.0 (and beyond) and fixed easy_install support. You should be able to easy_install the latest and greatest again.

Apologies for dragging my tail on posting Part II…

Keep on writing, great job!

Keep on writing, great job!

Had trouble with the mkdir

Had trouble with the mkdir command, probably a stupid question but do I need to be logged in as root to do it? Thanks.

Stan

Noel Edmonds, on some

Noel Edmonds, on some occasions has been the most-watched show on the channel.

Post new comment

The content of this field is kept private and will not be shown publicly.
By submitting this form, you accept the Mollom privacy policy.