Getting started with Mercurial

Welcome to Bitbucket, your community and home for Mercurial development! This guide will explain what Distributed Version Control means for you, and give a primer on how to get started using it.

(There's an excellent free book on Mercurial here: http://hgbook.red-bean.com/hgbook.html)

Introduction

Mercurial is a distributed version control system, or DVCS for short. It is in the ranks of Git and Bazaar, leading a new paradigm of working with version control.

If you have been using other version control systems like CVS or SVN, you might find this guide particularly useful, as it will draw parallels to those.

The main difference between a traditional version control system and a distributed one is that the distributed system does not rely on one central server. Every person with a repository also has the full history of changes. Each repository is independent. For newcomers, the notion of "no central place" might be scary, as it also means that there is no handling of conflicts in the central repository.

In Subversion, for example, each developer checks out a copy from the main server, works on changes, and commits them back in. In case of conflicting changes made by other developers, you will be notified and asked to merge the changes. In a DVCS world, this is different, as commits are local, and you can commit several dozens of changes locally without ever communicating with anyone else.

Philosophy

This new paradigm of distributed versioning allows for several things that centralized development does not. Specifically, it provides:

  • Allows commits/logs even when working offline
  • Drastic increase in speed for most operations
  • Ability for anyone to have their own copy of a project, and continue work without explicit "commit access"
  • No requirement to publish changes
  • No need to set up a server for version controlling things (self-contained)

Bitbucket

However, the centralized model has certain advantages, namely allowing instant sharing of changes, providing one “safe place” for a project, including backups, and a generally smaller merges.

Bitbucket attempts to compensate for this while at the same time maintaining the flexibility and benefits of DVCS. It does this firstly by providing a centralized location for a repository which provides a sharing-point for one or more developers to grow their code base. Secondly, it provides a set of tools that ease development and sharing of a code with the rest of the world.

Mercurial Primer

Enough fuzz, let’s get down to business. In Mercurial (hg for short, the chemical symbol for mercury), it's easy to get started. To create a new repository, simply write:

$ hg init

This will create a new repository in the directory you stand in. It will do so by creating a new directory, called .hg. This directory will maintain the list of changes you make, and some other metadata. You rarely need to do anything in this directory manually, so for now, just leave it.

If we inspect the directory, we will see the initial structure:

$ ls .hg/
00changelog.i   requires    store

These are the files hg creates in a new project.

To get started with a project, create a new file and tell hg to start tracking it:

$ emacs newfile.txt
# make changes and save file
$ hg add newfile.txt

You have now created a new file called newfile.txt and you have told hg that you want to keep it under version control. From this, hg knows that the next time you commit, it should record that. Lets try:

$ hg commit -m "Adding first file to repository"
$

Your file is now recorded. Notice that there is no output from the hg command. This is true for all hg commands that finish without error. No output, in most cases, means "everything OK."

Making changes

Now that you have your repository up and running, it's time to start making some changes.

For example, using our newly created repository from the last section, let us make a change to newfile.txt:

$ emacs newfile.txt
# make a change, save file

To see what hg thinks of this:

$ hg status
M newfile.txt

The M in the beginning of the line is hg's way of telling us that newfile.txt has been modified. Other common statuses are:

  • A means that the file is scheduled for addition (you have added it, but not yet committed it.)
  • R means that the file is scheduled for removal
  • ? means that the file is not tracked by hg

To record our change, we will again commit the file:

$ hg ci -m "Making a change here"
$

Your changes are now recorded. Notice that we used ci as shorthand for commit. You can also use st instead of status -- in fact, most commands abbreviate -- something very handy as you find yourself typing these commands over and over.

Publishing & receiving changes

One thing you get "for free" when using a central repository is that your changes are automatically made available for others to retrieve. This is of course also possible with hg, but since there is no central repository, you have to take a different route. Hg has a built-in serve command which will launch a local webserver on port 8000, where you can browse through your changes, and others can pull those changes from you. You may also store your repository on a remote computer, accessible over SSH.

What does pulling mean? It is roughly the equivalent to Subversion and CVS's update command, although it differs slightly. In Mercurial, the process of receiving and sending changes are is broken up into several steps to accommodate the flexibility you get from not being centralized.

In hg, you can pull from an origin, either from a local filesystem, HTTP or SSH. When you pull in changes, you won't actually touch any of the files you are currently working on, it will merely receive information about the remote changes and keep them in the local store.

To apply the changes pulled, you must update your repository. Updating will update your local files to the state you just retrieved, and it will also attempt to merge those changes with your local ones. You can think of pull+update as the update you're used to from Subversion or CVS. It's slightly different, but not much.

In the same manner, uploading your changes is referred to as pushing in hg. Pushing changes is roughly the equivalent to commit in Subversion or CVS. One major difference is that you can push any number of local changes to the remote repository; you don't need to do it for each one. If you are working on a feature, and you want to commit before it is done, you are encouraged to do so. Once you finish, you might have 1, 20, or even 500 local changes! Whenever you feel like it, you can push those changes to a remote repository for others to enjoy.

Why Bitbucket?

As mentioned earlier, Bitbucket attempts to provide means to ease this workflow. Basically speaking, Bitbucket allows you to create a repository on our servers, and gives you the opportunity to use our servers as your central location. Whether you are a one-man shop, working on private client projects, or a large team of developers, it is often necessary or useful to publish your code, not only for others to download, but also for collaborating successfully.

On top of that, we provide a friendly, feature-rich environment for visualizing changes, browsing repositories, comparing changes across revisions, and a sophisticated access control system that allows for you and your team to safely and efficiently work with your code. Mercurial in itself is a great system, and we merely provide an extra layer on top of it.

Where to from here

The next step on your journey to becoming a proficient Mercurial/Bitbucket user, is described in our next guide, Using Bitbucket.