A Guide to Using Mercurial

By Ken Gribble

2010

This document can be found at:

http://goo.gl/8troz

Table of Contents

A Guide to Using Mercurial

Introduction

Starting with Mercurial

Basic Configuration of Mercurial

Start a project

Making changes

Seeing differences

See the log

Using glog

Moving and copying

Basic Commands

Advanced Commands

Use with Linux and SSH

Create users, groups and a repo directory

Using the repository locally

Using the repository remotely

Group Workflow Suggestions

Other Uses

Backing up configuration files with Mercurial

Links and Tips


Introduction

This guide will cover basic use of the Mercurial. Specifically it covers the use of ssh as the method to access shared repositories, and suggests some guidelines for work-flow.

Starting with Mercurial

Basic Configuration of Mercurial

After installing Mercurial (see links below for installation instructions and download locations),  edit your user Mercurial configuration file, ~/.hgrc, and add the user interaction section to it, so Mercurial knows your name. While you are editing your Mercurial configuration file, you may as well add in the extension for glog. Add this set of lines to the bottom of your ~/.hgrc file::

[ui]

username = Ken Gribble

[extensions]

hgext.graphlog =

Now you can use the glog command in Mercurial (hg glog). More on that below.

Start a project

One might initialize a project like this.

Create a directory, some project sub-directories and files:

$ cd

$ mkdir MyProject MyProject/docs MyProject/bin

$ echo "This file will hold the introduction to MyProject" >> MyProject/readme.txt

$ ls MyProject/

bin  docs  readme.txt

Initialize the Mercurial repository and check the status:

$ hg init MyProject

$ cd MyProject/

$ hg status

? readme.txt

The “?” means the readme.txt file isn’t yet in the repository, add it like this:

$ hg add

adding readme.txt

$ hg status

A readme.txt

Make the first commit, creating a changeset:

$ hg commit -m "initial commit"

$ hg status

Making changes

Make some changes, then show the differences since the last changeset:

$ echo "The docs directory will hold documentation for MyProject" >> readme.txt

$ hg diff

diff -r c785efd2df41 readme.txt

--- a/readme.txt    Tue Jun 22 12:12:29 2010 -0700

+++ b/readme.txt    Tue Jun 22 12:13:49 2010 -0700

@@ -1,1 +1,2 @@

 This file will hold the introduction to MyProject

+The docs directory will hold documentation for MyProject

Seeing differences

Commit the changes, then for fun, check for differences and check the status:

$ hg commit -m "changes in documentation"

$ hg diff

$ hg status

See the log

Check the log to see your change-sets:

$ hg log

changeset:   1:44f40776ff5a

tag:         tip

user:        Ken Gribble

date:        Tue Jun 22 12:14:21 2010 -0700

summary:     changes in documentation

changeset:   0:c785efd2df41

user:        Ken Gribble

date:        Tue Jun 22 12:12:29 2010 -0700

summary:     initial commit

Using glog

The default log viewing with “hg log” is pretty boring and not as informative as using “hg glog”. The glog extension, that you set up earlier in your ~/.hgrc file, shows

Moving and copying

Always move or copy files using hg, so Mercurial knows to track the files:

$ ls

bin  docs  readme.txt

$ hg mv readme.txt ReadMe.txt

$ ls

bin  docs  ReadMe.txt

$ hg commit -m "moving a file"

$ hg log

changeset:   2:54e5536e412b

tag:         tip

user:        Ken Gribble

date:        Tue Jun 22 12:22:15 2010 -0700

summary:     moving a file

changeset:   1:44f40776ff5a

user:        Ken Gribble

date:        Tue Jun 22 12:14:21 2010 -0700

summary:     changes in documentation

changeset:   0:c785efd2df41

user:        Ken Gribble

date:        Tue Jun 22 12:12:29 2010 -0700

summary:     initial commit

And try a copy:

$ ls

bin  docs  ReadMe.txt

$ hg cp ReadMe.txt docs/ReadMe.txt

$ ls docs

ReadMe.txt

$ ls

bin  docs  ReadMe.txt

$ hg commit -m "copying a file to docs"

$ hg log

changeset:   3:b53b1b983fa0

tag:         tip

user:        Ken Gribble

date:        Tue Jun 22 12:23:32 2010 -0700

summary:     copying a file to docs

changeset:   2:54e5536e412b

user:        Ken Gribble

date:        Tue Jun 22 12:22:15 2010 -0700

summary:     moving a file

changeset:   1:44f40776ff5a

user:        Ken Gribble

date:        Tue Jun 22 12:14:21 2010 -0700

summary:     changes in documentation

changeset:   0:c785efd2df41

user:        Ken Gribble

date:        Tue Jun 22 12:12:29 2010 -0700

summary:     initial commit

Basic Commands

To see the basic commands for Mercurial, type:

$ hg

Mercurial Distributed SCM

basic commands:

 add        add the specified files on the next commit

 annotate   show changeset information by line for each file

 clone      make a copy of an existing repository

 commit     commit the specified files or all outstanding changes

 diff       diff repository (or selected files)

 export     dump the header and diffs for one or more changesets

 forget     forget the specified files on the next commit

 init       create a new repository in the given directory

 log        show revision history of entire repository or files

 merge      merge working directory with another revision

 pull       pull changes from the specified source

 push       push changes to the specified destination

 remove     remove the specified files on the next commit

 serve      export the repository via HTTP

 status     show changed files in the working directory

 summary    summarize working directory state

 update     update working directory

use "hg help" for the full list of commands or "hg -v" for details

Advanced Commands

To see the full list of commands, type hg help or “hg -v”:

$ hg help

Mercurial Distributed SCM

list of commands:

 add          add the specified files on the next commit

 addremove    add all new files, delete all missing files

 annotate     show changeset information by line for each file

 archive      create an unversioned archive of a repository revision

 backout      reverse effect of earlier changeset

 bisect       subdivision search of changesets

 branch       set or show the current branch name

 branches     list repository named branches

 bundle       create a changegroup file

 cat          output the current or given revision of files

 clone        make a copy of an existing repository

 commit       commit the specified files or all outstanding changes

 copy         mark files as copied for the next commit

 diff         diff repository (or selected files)

 export       dump the header and diffs for one or more changesets

 forget       forget the specified files on the next commit

 grep         search for a pattern in specified files and revisions

 heads        show current repository heads or show branch heads

 help         show help for a given topic or a help overview

 identify     identify the working copy or specified revision

 import       import an ordered set of patches

 incoming     show new changesets found in source

 init         create a new repository in the given directory

 locate       locate files matching specific patterns

 log          show revision history of entire repository or files

 manifest     output the current or given revision of the project manifest

 merge        merge working directory with another revision

 outgoing     show changesets not found in destination

 parents      show the parents of the working directory or revision

 paths        show aliases for remote repositories

 pull         pull changes from the specified source

 push         push changes to the specified destination

 recover      roll back an interrupted transaction

 remove       remove the specified files on the next commit

 rename       rename files; equivalent of copy + remove

 resolve      retry file merges from a merge or update

 revert       restore individual files or directories to an earlier state

 rollback     roll back the last transaction

 root         print the root (top) of the current working directory

 serve        export the repository via HTTP

 showconfig   show combined config settings from all hgrc files

 status       show changed files in the working directory

 summary      summarize working directory state

 tag          add one or more tags for the current or given revision

 tags         list repository tags

 tip          show the tip revision

 unbundle     apply one or more changegroup files

 update       update working directory

 verify       verify the integrity of the repository

 version      output version and copyright information

additional help topics:

 config       Configuration Files

 dates        Date Formats

 patterns     File Name Patterns

 environment  Environment Variables

 revisions    Specifying Single Revisions

 multirevs    Specifying Multiple Revisions

 diffs        Diff Formats

 templating   Template Usage

 urls         URL Paths

 extensions   Using additional features

use "hg -v help" to show aliases and global options

Use with Linux and SSH

A Mercurial repository can be accessed via the ssh protocol as long as one has a linux/unix account on the machine the repository is on, as well as appropriate permissions. This section will explain how to create a repository for use with a group of developers.

Create users, groups and a repo directory

On the server of choice, make sure you have all the developers have user accounts and that all the accounts are in a unix group of choice, (mygroup in these examples).

To create the repo directory with proper permissions:

$ sudo mkdir MyProject

$ sudo chgrp mygroup MyProject

$ sudo chmod 775 MyProject

Create some infrastructure for the project, and initialize the repository:

$ mkdir MyProject/docs MyProject/bin

$ hg init MyProject

$ cd MyProject

$ echo "MyProject introduction file" > readme.txt

$ hg add

adding readme.txt

$ hg commit -m "first commit"

$ hg log

changeset:   0:4cb4af489c5f

tag:         tip

user:        Ken Gribble <gribble@cs.ucdavis.edu>

date:        Tue Jun 22 13:27:32 2010 -0700

summary:     first commit

Then one could make some changes:

$ hg cp readme.txt docs

$ ls docs

readme.txt

$ hg add

$ hg status

A docs/readme.txt

$ hg commit

$ hg log

changeset:   1:7d050f666494

tag:         tip

user:        Ken Gribble <gribble@cs.ucdavis.edu>

date:        Tue Jun 22 13:31:46 2010 -0700

summary:     Doing some copying.

changeset:   0:4cb4af489c5f

user:        Ken Gribble <gribble@cs.ucdavis.edu>

date:        Tue Jun 22 13:27:32 2010 -0700

summary:     first commit

Using the repository locally

To clone this repository locally, one would run this command:

$ hg clone /home/REPOS/MyProject

destination directory: MyProject

updating working directory

2 files updated, 0 files merged, 0 files removed, 0 files unresolved

$ ls MyProject/

docs  readme.txt

Note that the bin directory is missing. Mercurial only keeps track of files, so if one added a file in bin it would show up, much like the docs directory did because of the previous copying of the readme.txt file.

Using the repository remotely

To clone this repository remotely, one only need to use the ssh URL:

ssh://[user[:pass]@]host[:port]/[path][#revision]

This is the command line to use for our example, on your.server.edu, with user gribble and MyProject repo in /home/REPOS -- Note the needed use of the double slash “//” to indicate the root directory:

$ hg clone ssh://gribble@your.server.edu//home/REPOS/MyProject

destination directory: MyProject

requesting all changes

adding changesets

adding manifests

adding file changes

added 2 changesets with 2 changes to 2 files

updating working directory

2 files updated, 0 files merged, 0 files removed, 0 files unresolved

$ ls MyProject/

docs        readme.txt

Group Workflow Suggestions

Now that basic Mercurial use has been explained, including how to use ssh, please read Learning Mercurial in Workflows. The section called “Using a shared repository” should be very useful.

Other Uses

Backing up configuration files with Mercurial

System Administrators like to back up configuration files, but what a pain that can be with a directory full of backup copies. Mercurial to the rescue!

Simply initialize Mercurial for the directory where the configuration files exist (/etc for example), then add the files you want to control -- or add every file in the directory. Don't forget to commit them as you make changes, and take nice commit log notes on what work you are about to do, or what work you have committed.

Now you, and your teammates, have a running log of changes, can do diff’s to see what exact changes were made, can rollback to a previous changeset, and other powerful, quick, and clean commands.

Links and Tips

A workflow tip from Sebastian Ng:

Hi Ken,

After going through some crazy troubles with Jonathan on mercurial, we ended up nuking our repository and restarted a new repository and tried it out again. To prevent trouble in the future, I'll share with you the procedure we're doing now:

1) hg pull

2) After pulling, update. If updates have some issue, merge. If merge has issues, try resolving them manually

3) If you did a merge on step 2, commit changes.

4) Make the changes you want

5) Before pushing, commit with the option "--close-branch"

6) Then push. Do not use the -f option.

The trouble we kept having is that we kept having multiple heads being created. I think the number of heads grew so much that it was causing inconsistency among different repos. Hopefully, this procedure fixes things.

-Sebastian

Mercurial

http://mercurial.selenic.com/

Download

http://mercurial.selenic.com/downloads/

Command line Installation

Ubuntu/Debian:

Command: $ apt-get install mercurial

CentOS/Fedora

Command: $ yum install mercurial

Host your own Mercurial repository with hg-ssh

How to Collaborate using Mercurial with hg-ssh