8 min read

(For more resources related to this topic, see here.)

Getting ready

Now that you have Mercurial set up on your computer, you are going to use it to track all the changes that can happen in a configuration directory, for example, in the configuration files of Apache2 (a web server). It could of course be used in any other type of directory and files: your home directory configuration files, some personal development projects, or some Mozilla Firefox configuration files such as user.js and prefs.js, and likewise. If you do not have Apache2 installed on your computer, you can do the same type of exercises, for instance, in $HOME/src. Also, with the owners of the /etc/apache2 files being root, you will need to change their owner to your account. For example, your username/group both being mary/mary:

$ sudo chown -R mary:mary /etc/apache2/

How to do it…

  1. The first thing to do is to initialize a new repository by typing these lines:

    $ cd /etc/apache2/
    $ hg init

  2. You can then show the status of the files in your new repository, that is, which files are tracked and which are unknown to Mercurial, and also which files have changed, which have been deleted, and so on. This is done using the Mercurial status command:

    $ hg status
    ? apache2.conf
    ? conf.d/charset
    ? […]? sites-available/default-ssl
    ? sites-enabled/000-default

  3. As you can see, everything is untracked right now. The way to tell Mercurial which files you want to be version controlled and added to your newly created repository is by using the add command. For example, if you want to track changes in the apache2.conf file, and all the files of the sites-available directory, you need to type:

    $ hg add apache2.conf sites-available/

  4. Showing the status again, Mercurial now tells us that three files have been added (by showing A, which denotes Added ; instead of ?—, denoting Unknown , in front of its path):

    $ hg status
    A apache2.conf
    A sites-available/default
    A sites-available/default-ssl
    ? conf.d/charset

  5. Now if you want to record the initial version of these files (the one provided by your distribution), you need to use the commit command and add a log message using the -m option:

    $ hg commit -m"initial version"

  6. Using the log command, you can print the entire history of your repository (here you used commit only once, so only one change—called a changeset —is listed):

    $ hg log
    changeset: 0:7b3b5fcb16d0
    tag: tip
    user: Mary […date…]summary: initial version

  7. Whenever you change a file, you can record the modification in Mercurial with the commit command. Let’s type the following sequence using the status, diff, commit, and log commands:

    $ vi apache2.conf
    ..make some changes: add "# new line" at the end of the file
    $ hg status -m
    M apache2.conf
    $ hg diff
    diff -r 7b3b5fcb16d0 apache2.conf
    […]+# new line
    $ hg commit -m"added a line at the end"
    $ hg log
    changeset: 1:02704fcf58b1
    user: Mary
    summary: added a line at the end
    changeset: 0:7b3b5fcb16d0 […]

  8. You can also reverse the modifications; for instance, if you modify a line again in apache2.conf, such as changing # new line by # new linez, using the diff command, you can see your modification:

    $ hg diff
    diff -r b0d2bfb95d81 apache2.conf […]-# new line
    +# new linez

  9. It is then possible to come back to the latest saved version using the revert command:

    $ hg revert apache2.conf
    $ hg status
    ? apache2.conf.orig
    $ tail -1 apache2.conf
    # new line

  10. At this stage, you can’t see the M apache2.conf file any more, and the value at the last line is the one that is not modified, but there is a new file called apache2.conf.orig; this is because the revert command saves your modifications in a backup file. You can either delete it afterward or you can use the –no-backup option if you know what you do. Mercurial has a conservative philosophy to avoid losing data.
  11. Finally, if you realize that you do not need a file any more, you can remove it from being version controlled and from your working directory by using the remove command. For example, if you don’t need the SSL configuration file of Apache, you can remove it by typing:

    $ hg remove sites-available/default-ssl
    $ hg status
    R sites-available/default-ssl
    Instant Mercurial Distributed SCM Essential How-to
    $ hg commit -m"removed unused ssl conf file"
    $ ls sites-available/

  12. Note that the file has disappeared from your working directory, and even if you create a file with the same name, it will not be version controlled anymore (unless you add it again). But, of course, it is still possible to get it back or to get a version of apache2.conf exactly how it came with the distribution. In order to do that, you need to use the update command and ask to switch to revision 0:

    $ hg update -C 0
    $ ls sites-available/
    default default-ssl
    $ tail -1 apache2.conf
    Include sites-enabled/

  13. In order to switch back to the latest revision (it is coined the tip), you can just call update again with no revision passed as an argument:

    $ hg update -C
    2 files updated, 0 files merged, 1 files removed, 0 files

How it works…

With this sequence, you already know how to manage versions of your personal projects: save a version, undo a change, retrieve an older version, and so on. Let’s take a closer look at what happens under the hood.

After you type hg init, a directory called .hg is created:

$ ls -a
. apache2.conf envvars magic mods-enabled sites-availabl
.. conf.d .hg mods-available ports.conf sites-

This directory, called a repository, contains the history of your project and some Mercurial metadata. This is where Mercurial records all your revisions of tracked files (actually, it stores only the differences between each revision, like RCS/CVS/Subversion, and in compressed form, so the size is usually less than that of the the actual data!). And also, this is where it stores the commit messages, information about branches, tags, bookmarks, and so on. All the other files and directories beside .hg are your project files; they form what is called a working directory. If ever you would like to forget version control in this zone, you can just remove the .hg directory.

Another interesting thing to note is that, contrary to Subversion for instance, in a local .hg repository, you do not have less information than in a repository in a central server! Your installation of Mercurial actually allows you to have both a client command (or GUI), with which you can work locally or with distant servers, and a server, with which you can share your work with colleagues. This is because, with DVCS ( Distributed VCS ), there is no difference between the data checked out to work with and the data ready to be published. When you either create a local repository or clone an existing one from a server, you have all the necessary information (in the .hg directory) to become a publisher yourself.

There’s more…

This section will discuss supplementary commands or options.

Other commands

First of all, Mercurial has many commands (the list of which you can get with the command hg help); in addition to adding and removing files from being version controlled, you can also use the copy command to copy a file into a new file, and similarly, you have a rename command. The difference between the OS file copy and the one that Mercurial has is that when you receive a change made by somebody else to the original file, it will also be applied by Mercurial to the new file; but for this magic to work, you have to tell Mercurial about the copies/renames so it can track them. There are also convenient commands, such as addremove, which allows you to automatically add all new files and remove (from version control) files that have been deleted.


Please refer to the built-in help system or to reference documentation, such as Mercurial: The Definitive Guide, available online at o http://hgbook.red-bean.com/, to get the complete list of options for each command. You have seen -m (or –message) in the commit command to specify a log message; if you omit this option, Mercurial will prompt you to get a message using $EDITOR. Also, you have seen -C (or –clean) in the update command; it will tell Mercurial to discard uncommitted changes when switching to another version (otherwise, local changes would automatically be merged into the requested version).


This article explained how to work with local files, either personal projects or files that you wanted to be version controlled (for example, source code or configuration files). You also learned how to create a new repository, make changes, and track them (selecting files to track, recording changes, and reversing those changes).

Resources for Article :

Further resources on this subject:

Subscribe to the weekly Packt Hub newsletter

* indicates required


Please enter your comment!
Please enter your name here