What is Mercurial?

Mercurial is a Version Control System that stores all the versions locally while many VCSs rely on the internet to store older versions of the files. It allows users to rever to previous versions of files if necessary as well as collaborate asynchronously on projects and merge their results.

Installing Mercurial on Mac OS X

Check if you have Mercurial

Open a terminal window (/Applications/Utilities/Terminal) and type:

hg

If it returns something similar to:

Mercurial Distributed SCM
basic commands:

It means you have Mercurial already installed. If not, follow the instructions below to install Mercurial:

Getting the right version for your OS and Python interpreter

First, check which operating system version you are using by navigating to the top left corner of your screen and click on:

 > About This Mac > Version 10.X

Now, get the version of python that you're using by typing the following in a terminal window:

python --version

With this information, go to http://mercurial.selenic.com/downloads/ and select a version that matches both your Mac OS and Python versions. Pay particular attention to the filename linked to by the different download links as they contain the python version in them but are not otherwise written explicitly on the website. An example of a filename is:

Mercurial-2.3.1-py2.7-macosx10.8.zip

Indicating that this installation package of Mercurial is expecting python 2.7 and OS X 10.8

Heads up! If you cannot find a versions that satifies both your Mac OS and Python version, prioritize matching for the Mac OS version. If need be you can install a newer version of Python alongside the native Mac one and point Mercurial to that (Google it :)).

Setting computer up to use the archive

SSH Overview

SSH is a secure communication mechanism that relies on asymetric encryption (also called public-key cryptography). The authentication mechanism uses a public key to decrypt the server's messages and a private key to prove to the server that we are allowed to communicate. This means that we must ensure that the private key file stored on your computer is adequately protected from unauthorised users. This is done through changing the key file's permissions (see Terminal commands section below).

Configurating SSH

The first thing we need to do is to obtain the keys for the archive you want to use, which in this case are distributed by Neil via email to the accepted students. This will contain two files: classes and classes.pub. The former being the private key and the latter being the public one. We now need to place them in a logical directory located in ~/.ssh/keys. Let's first check that the directory exists:

ls ~/.ssh/keys

If the directory doesn't exist, you can create it by using the following command:

mkdir ~/.ssh/keys

Now that we have the folder created, copy the archive keys you're going to use into the folder. You can do this in many different ways. The simplest is probably to open a finder window and drag and drop the key files into the folder. Because folders that start with a . are hidden folders on UNIX operating systems, you can use the command line to open the finder to the correct location:

open ~/.ssh/keys

Alternatively, you can use the copy command to copy the correct files. Remember you can use wildcards like * to copy multiple files at once

Key file permissions

As discussed in the SSH overview above, we need to make sure the keys have the correct permissions set, otherwise it represents a risk and SSH won't let you connect to the archive. Let's check the permissions of the files in the Keys folder:

ls -la ~/.ssh/keys

Permissions for the .pub key(s) should be:

-rwxr-xr-x

and permissions for the private key file(s) should be:

-rw-------

This is unlikely to be the case right out of the box. So type the following commands to respectively change the public files in the folder:

chmod u+rwx *.pub chmod go+rx *.pub chmod go-w *.pub

and the private file of interest, in this case classes:

chmod u+rw classes chmod go-rwx classes

Cloning the archive

Now that we have the SSH keys configured correctly, we need to clone the archive to our local computer. Because the command is a little long, some people prefer to automate the process by creating a custom script. Please see that section if you want to go that route. Otherwise, use the command below and replace with your relevant settings.

hg clone -v -e 'ssh -p port_number -i ~/.ssh/keys/private_key_file' ssh://hg@server_location/archive_name local_folder_path

An example of this command being used to clone the How to Make (Almost) Anything Class archive for 2012 (xxx.12):

hg clone -v -e 'ssh -p 846 -i ~/.ssh/keys/classes' ssh://hg@fab.cba.mit.edu/863.12 HTMaA

Now that we've cloned the archive, we need to configure the archive's

Creating custom scripts Optional

Note
Please note that the /usr/bin is used by your system to store many programs. So if my mistake you delete things from there, you can cause quite a problem to the normal operation of your computer. For this reason, some people prefer storing custom / programs in the /usr/local/bin. However, in order to be able to access your script from the command line you first need to add that folder to your path.

In order to create a script that will automate the process outlined above, we will need to create a program in the correct folder. In this example, I will use the /usr/bin folder to store our script. Please read the note about this folder on the side if you want to use a less essential folder. Because of the folder's importance for the system, we need to use super-user privileges to be able to write our script to the folder:

sudo nano /usr/bin/hgclone

An interface appears in your terminal. Copy and Paste the following script:

#!/bin/bash
#
if [ $# -ne 4 ]; then
   echo "Incorrect use of hgclone. Please run command thusly:"
   echo "hgclone archive_name archive_key archive_server server_port"
else
   cmd="hg clone -v -e 'ssh -p $4 -i ~/.ssh/keys/$2' ssh://hg@$3/$1 $1"
   eval $cmd
   cmd="echo -e '\n[ui]\nssh = ssh -p $4 -i ~/.ssh/keys/$2' >> $1/.hg/hgrc"
   eval $cmd
   fi
                

To save the script and exit the nano text editor, press Ctrl-X, confirm (using the Y key and Enter). You should now be back to the terminal. Try executing the script you just saved by doing:

hgclone

It should complain that you didn't run the script with the correct arguments. Now, all that should be left for us to do is run the script. If you have other issues running the script, check that you have execute (u+x) permissions on the hgclone file (/usr/bin/hgclone).

An example of the hgclone command would be:

hgclone 863.12 classes fab.cba.mit.edu 846

Pulling from the archive

This one is easy. The command is below.

hg pull

Don't forget to incorporate the pulled changes into your local directory:

hg update

Occasionally when your version clashes with the one you are trying to update, you might get an error telling you there are outstanding changes or that you need to merge. See the merging section below on how to do that.

Adding and committing changes

Show the current status of your local archive

The first thing you need to do when adding changes to the archive is to check the status of the archive using the following command:

hg status

This should return a list of the files like the one below:

M people/charles.fracchia/vcs.html
? people/charles.fracchia/about.html

The M flag represents a file that is tracked by mercurial but has been modified since the last commit. The ? flag means that the file is not being tracked by the version control system.

Adding and forgetting files

In this case, I recently created this about.html page, and want to include it in the next commit. To do that, I use the command below:

hg add people/charles.fracchia/about.html

Re-running the status command should now show that the file will be added to the next commit:

M people/charles.fracchia/vcs.html
A people/charles.fracchia/about.html

If afterall you change your mind and don't want to include the file to the next commit use the forget command:

hg forget people/charles.fracchia/about.html

Committing

Committing in mercurial is akin to creating a snapshot in time of your archive. You could refer to this as a version of your archive. Once you have selected the files that should go into your commit (see Adding and Forgetting section), you can commit your version by using the following command:

hg commit -m "Your commit message"

Try to be descriptive in your commit message, it will be extremely helpful when you have to look back and understand what was done.

Merging

Merging occurs when you have two parrallel branches of development that need to be unified. This often happens when you have been offline (aka haven't pulled and updated your archive) in a while and changes have been made in parallel. Sometimes, these changes will conflict with eachother and you will need to actively choose which changes to keep and which you throw. I will not be explaining how to do this, there is a good guid on this here.

In order to merge your changes into the current head commit type:

hg merge

As mercurial suggests after the merge command, don't forget to commit that merge into a version. I often use an explicit comment to show this specific merge:

hg commit -m "Merging"

Pushing

Pushing to the archive uploads your commit history to the server. This means that you can make intermediary versions (and encouraged) as you go along, even if you can't reach the server. Once you restore your ability to connect to the mercurial repository server, you can upload your changes using:

hg push

Terminal commands

Summary of some useful terminal commands. ^ indicates the Ctrl key. ~ means the home directory (aka: /Users/username)
Syntax Description Example
pwd Give the path of your current directory pwd
/Users/username
open dir Open the directory dir in Finder. ".." goes one level up in the folder structure. "." means the current folder. open .
cd dir Change the current directory to dir cd ..
ls options List the contents of the current directory. If you put a path in the options, it will list the contents of that path. Adding "-la" will list the hidden folders ls -la
-rw-------@ 1 username staff 1675 Sep 12 23:57 classes
chmod User Group Other+/-Read Write eXecute file_path Change the permissions on the file chmod go-rx file
Would remove read and execute rights from group and other on file
cp original_file target_file_location Copy original_file to target_file cp ~/Desktop/classes.pub ~/.ssh/keys/classes.pub
Would copy the classes.pub file from the desktop to the ssh keys folder
sudo command Execute command with superuser privileges sudo chmod ugo+rw protected_file
Would change the permissions of the protected file to be readable by all (user, group and other)