Mercurial for SVN Users

From GeeklogWiki
Jump to: navigation, search

This is an attempt at giving a quick introduction to Mercurial for those familiar with more "traditional" version control systems, e.g Subversion or CVS. Please replace "SVN" with "(or any other non-distributed VCS you may be familiar with)" in the following text.

3 ops vs. 5 ops

When using SVN, the most common operations you'll do are

  • checking out a repository
  • committing a change to the repository
  • updating to get the changes other people made to the repository

These things aren't really different in Mercurial - apart from one detail:

hg clone does the initial checkout of a repository. In addition to checking out the files, though, you also get a complete working local copy of the repository.

Consequentially, when you commit changes using hg commit, you only commit them against your local repository. hg up also only updates from the local repository.

So we need two more commands to sync with our "parent" repository:

  • hg push pushes any locally committed changes to the other repository
  • hg pull pulls other people's changes into your local repository

In other words, to get the exact same effect as in SVN:

  • hg pull + hg up == svn up
  • hg commit + hg push == svn commit

Workflows

However, when working on something, you don't usually push every change immediately. Instead, use the benefits of version control locally until you have reached a point where you think your work is ready for others to use and only then do the push.

Additionally, having a local repository also lets you work offline. Push your changes when you're back online again.

With SVN, checking something in immediately makes it available to others. And since that means that you risk breaking something, people tend to work on something locally for a long time before checking changes in, which also means that changes are often huge and tend to cover more than one aspect.

The Mercurial documentation recommends using a clean "incoming" repository that you only use to sync with the parent repository. From that repository, you can then easily create local clones. The recommendation here is to have one clone for every feature or bugfix you're working on.

So when you're in the middle of implementing a new feature (with some commits already in your local repository that you don't want to push just yet) and you run into a bug - what do you do? You create a new clone of the incoming repository, fix the bug there, then push back that change to the remote repository. You can then sync the bugfix back (via your incoming repository) into your other work repository and continue working on that new feature.