Using Mercurial
Contents
Introduction
Mercurial is a distributed version control system (DVCS). The differences to a "traditional" centralized VCS (like CVS or Subversion) include:
- Users get a self-contained repository that they can commit changes to, even when being offline.
- Changes can be pushed back to the parent repository or even to other repositories.
Having used CVS since its inception, Geeklog switched to Mercurial after the release of Geeklog 1.5.1. This switch was preceded by an successful experiment using Mercurial during the 2008 Google Summer of Code. The distributed model did fit this scenario nicely, as each of our students was working on a separate feature. So they had a local repository to check in to (giving them all the benefits of a version control system). Once a feature or part of a feature was done, it could be pushed back to the parent repository. And in the meantime, it was easy to let other people, e.g. their mentor or interested members of the Geeklog community, pull the changes from the student's repository to show things off or get help on a problem.
Installing Mercurial
Installation instructions are provided for Windows, Mac OS X, and Linux
Setup
Geeklog's Mercurial repository is available from this URL:
This repository was converted from the CVS repository right after the release of Geeklog 1.5.1.
To create a copy of that repository, simply do
hg clone http://project.geeklog.net/cgi-bin/hgwebdir.cgi/geeklog/ geeklog
Where the last "geeklog" is just a directory name for the local copy (and can be changed at will). This will give you a fully working local repository that you can commit changes to.
Note: The same URL can also be used to browse the repository online. Simply visit that URL with your web browser.
SSH Setup
For ssh access, you need an account on the server. So this is only of interest for the core developers and SoC students.
You can clone the repository via SSH like so:
hg clone ssh://username@cvs.geeklog.net//cvsroot/hg/geeklog geeklog
Where "username" is your login name and the "geeklog" at the end of the command line is again simply a name for your local directory.
Please note the slightly odd path syntax with the two slashes after cvs.geeklog.net - those are required.
Pushing back
Being able to push changes back to the repository again requires an account on the server. You can either do
hg push ssh://username@cvs.geeklog.net//cvsroot/hg/geeklog
or, to make your life easier, set the default-push repository in the .hg/hgrc file of your local repository like so:
[paths] default-push = ssh://username@cvs.geeklog.net//cvsroot/hg/geeklog
(Again, in the ssh: URLs above, replace "username" with your login name)
Trust and Notifications
Changes pushed back into the central repository will trigger an email sent to the geeklog-cvs mailing list. However, that email will only be sent after the following additional steps:
- log into your account on cvs.geeklog.net
- in your home directory, create a file named .hgrc
- enter this as the file's content:
[trusted] users = geeklog2 groups = users
This will also get rid of warnings like
- remote: Not trusting file (...) from untrusted user geeklog2, group users
when pushing back changes.
GSoC Repository
The repository used during the 2008 Google Summer of Code is still available from
Note that both the URL and the repository name have changed (formerly Geeklog-SoC). You can still use your local copies of that repository - you only need to update the default-push setting to the new address and name.
Best practices
Since we're all new to Mercurial, this is something we will have to establish as we go along. For starters, the Mercurial Wiki has a page on Working Practices that we may want to adopt.
Use a clean incoming repository
Pull changes to a local "incoming" repository but don't work on that repository. Cloning that repository locally is a cheap operation and allows you to easily create multiple copies if necessary, e.g. when working on different features in parallel.
Push directly from your working repositories, then sync back by pulling the changes back down via your incoming repository.
Merging
If you attempt to push changes to the main repository and receive the error:
pushing to ssh://username@cvs.geeklog.net//cvsroot/geeklog/Geeklog-SoC searching for changes abort: push creates new remote heads! (did you forget to merge? use push -f to force)
Simply pull from the main repository, "hg heads" to see the revision numbers, "hg merge [rev number]" to merge your changes, then commit the changes, and push back to the main repository.
Also: Don't try to push newly added files while you still have uncommited changes lying around (or you will end up with the above). In that case, it may make sense to make a fresh clone (fast + cheap if you use an "incoming" repository!), add the new files there, then push from the fresh copy.
Username
When committing a change, the username associated with that change will be your local username (login, etc.) - not the name of your account on the server.
For a consistent username, add your preferred username to your local .hgrc file:
username = John Doe <john@example.com>
The email address is optional.
(More tips and tricks to be added here)
Undoing Changes
To undo changes you made, use one of the following, depending on circumstances:
- hg revert
to revert changes made before a commit. This will also undo hg add and hg remove. - hg rollback
to revert changes that have been commited to the local repository but not been pushed to another repository yet. You can only rollback the last hg command. - hg backout
to revert changes after they have been commited and pushed.
Note that hg backout will actually add a new change to the current branch that reverts your previous change. I.e. your change will not be removed from the repository. Unless you've accidentally committed something super-secret, that's usually fine. Mistakes happen - no need to sweat it.
Documentation
The Mercurial Wiki is a good place to search for information. For starters, however, Distributed revision control with Mercurial aka "the hg book" is a much better place to start. This book is available for download under the Open Publication License.
Here's the entirely subjective "The Impatient's Guide to the HG Book":
- Chapter 1: Introduction
Skip if you already know about VCS and DVCS - Chapter 2: A tour of Mercurial: the basics
Everything from section 2.2 on is recommended reading. The essential things you need to know to use Mercurial. - Chapter 3: A tour of Mercurial: merging work
Title says it all - recommended reading - Chapter 4: Behind the scenes
Feel free to skip - Chapter 5: Mercurial in daily use
Despite the title, this chapter seems more confusing than helpful - skip - Chapter 6: Collaborating with other people
Section 6.2 is recommended reading once you've mastered the basics - Chapter 7: File names and pattern matching
Nothing surprising here - skip - Chapter 8: Managing releases and branchy development
Advanced topic but useful - Chapter 9: Finding and fixing your mistakes
Very useful (but skip sections 9.5 and 9.6) - You can effectively stop reading after Chapter 9.
- Appendix A may be useful as a reference.
Windows Users - Secret Sauce (if you have commit rights)
I'm using command line Mercurial (I don't like the windows explorer performance hit of the tortoise system). But this works for me, after much messing around.
- Clone the main Geeklog repository, as above. (geeklog-hg)
- Clone your local copy of Geeklog to give yourself a clean working environment. (geeklog-hg-mine)
- Clone your clean working environment ;-) (geeklog-hg-dev)
- Update /path/to/geeklog-hg/.hg/hgrc to match bellow
- Update /documents and settings/[your user]/mercurial.ini to match the other bellow
And that works.
For hgrc:
[paths] default = ssh://[your username]@cvs.geeklog.net//cvsroot/hg/geeklog
For mercurial.ini:
[ui] ssh = c:/path/to/putty/plink.exe -ssh -v -l [your username] -pw [your password] username = [your name] <[your email address]>
So I develop in geeklog-hg-dev, then I winmerge my changes back into geeklog-hg-mine to make sure I never accidentally commit localsettings (paths etc) or hacks, debugs. Then I commit to geeklog-hg-mine, then back to geeklog-hg when that's ready, then push up to master. Complex hey? ;-)