Mercurial cheat sheet
This page contains everything you need to know to use the Mercurial version control system for the labs in the Compilers course. Material for the labs is provided in a public, read-only Mercurial repository.
- You will begin by cloning the repository into your home directory.
- Then you can work on the labs by editing the files locally.
- As you work, you may like to check in your changes to your local repository in order to keep track of what you've done.
- At any point, you can check the status of files you have changed, view a log of what you have checked in, and compare the state of your work with the checked-in version or with original code provided for the lab.
- If there are bug fixes or additions to the lab materials during the course, you can get them by pulling and merging changes from the public repository.
One element of a typical workflow is missing in the lab setup: because each person is doing the exercises independently, we omit the step where you push your changes back to the public repository.
The minimum you will need to do is clone the public repository to begin the labs, and produce some diff listings as a part of your report on the assignment. Anything more is entirely optional. If you want to know more about Mercurial, I suggest you begin with an online tutorial written by Joel Spolsky.
The lab materials are provided in a Mercurial repository on Mike's college computer, the same machine that hosts Spivey's Corner. To begin the labs, you should issue the command,
$ hg clone http://spivey.oriel.ox.ac.uk/hg/compilers
This will create a directory named
compilers with subdirectories corresponding to the Keiko virtual machine and to the four lab exercises, among others, all containing the files that make up the lab materials.
Like all commands that interact with Mercurial, this one begins with
hg – the chemical symbol for Mercury – and then the name of the specific operation that is needed, in this case
The clone command given above depends on Mike's computer being available, and that will not be true forever. As an alternative, you can use Mercurial to clone a Git repository maintained in the Computer Science department: details below.
Your next act, as suggested in the lab manual, will be to change to the subdirectory
compilers/keiko and build the software that supports the virtual machine:
$ cd compilers/keiko $ make
compilers created by the
clone command contains the subdirectories you can see, plus one hidden subdirectory
compilers/.hg; it is in this subdirectory that Mercurial keeps a complete copy of the repository that you cloned, together with any changes or additions you make.
After you have done some editing, the command
$ hg st .
lists the files in your current directory ("
.") that do not agree with the latest state of the repository. The output might look like this:
M kgen.ml ? inicheck.ml ? kgen.ml~ ? inicheck.cmo
This means that the file
kgen.ml has been modifed since the last check-in, and there are files
inicheck.cmo that Mercurial knows nothing about. You can add the new source file to version control by giving the command
hg add inicheck.ml, and afterwards
hg st will show an
A in place of the question mark. It's not appropriate to add the backup file
kgen.ml~ or the object file
inicheck.cmo, because they are not part of the source code for your program.
If there are no changes since the most recent check-in, then
hg st produces no output.
hg st . shows modified or added files in the current directory, then the command
$ hg ci . -m "log message"
will record these changes in the repository. Here
log message represents a brief comment you should write, describing the changes you are checking in. Larger projects typically have conventions that demand longer and more explicit comments with every check-in; then it is more convenient to omit the comment from the command line, and have Mercurial start an editor for you to type as long a comment as is needed. But, for us, a few words on the command line are sufficient.
It's a good idea to check in the main part of each lab exercise before starting on the next one, and to check in again when you have finished everything for an exercise. At that point, you can pull and merge any updates that have been made to the lab materials (see below).
Mercurial records your name next to each change you check in, and that means the
hg ci command needs to know it. You need to create a file in your home directory called
.hgrc and in it put the following text:
[ui] username = Fred Bloggs <email@example.com>
(substituting, of course, your real name and e-mail address for the strings
Fred Bloggs and
firstname.lastname@example.org). After you've created this file, the unix command
ls will not show it, because of the long-standing unix convention that files with names starting with a dot are not listed. But the file does exist, and you can see it listed, together with no doubt 1001 other such hidden files, by giving the command
$ hg log
will show a list of checked-in revisions, starting with the lab materials as you inherited them and showing also any revisions you have checked in.
hg diff command can be used to compare any two revisions of your project or some of its files. The simplest uses are the simple command
$ hg diff .
with no arguments; this compares the current directory in the working copy with the latest check-in. Example output:
diff -r 13c2e7a5d54c lab2/kgen.ml --- a/lab2/kgen.ml Tue Jun 26 22:41:15 2012 +0100 +++ b/lab2/kgen.ml Tue Jun 26 23:11:42 2012 +0100 \@\@ -83,11 +83,11 \@\@ gen (CALL 0) | IfStmt (test, thenpt, elsept) -> let lab1 = label () and lab2 = label () in - gen_cond false lab1 test; - gen_stmt thenpt; + gen_cond true lab1 test; + gen_stmt elsept; gen (JUMP lab2); gen (LABEL lab1); - gen_stmt elsept; + gen_stmt thenpt; gen (LABEL lab2) | WhileStmt (test, body) -> let lab1 = label () and lab2 = label () in
(The lines marked
- have been removed and replaced by those marked
Also useful in the labs is the command
$ hg diff -r basis .
This compares the working copy with the original source code, bookmarked as
basis, showing exactly the changes you have made. The bookmark
basis is always updated to point to the unmodified source without your changes, even if you have merged in changes to the lab materials after starting work on a lab.
Pulling and merging changes
If we need to fix bugs in the lab materials during term, or to add more example programs, then the changes will be added to the public repository for you to pull in and merge with your own changes. If the need arises, we'll help you with the process; but very briefly, the procedure is as follows. First, pull the changes from the public repository into your own. This will not change any of the revisions you've checked in, nor your working copy, but it will make the bugfixes available locally.
$ hg pull
Next, you should check in the work you've done so far, so as to give you a safe place to return to if anything goes wrong.
$ hg ci -m "Checkpoint before merging"
This will probably create a fork in your repository, where one revision (typically the one present when you cloned initially) now has two children, one containing your own work, and the other containing the fixed public materials. You now need to merge these together into a single revision. Mercurial will work out what to do:
$ hg merge
The merged revision is now present in your working copy, and you should check it in.
$ hg ci -m "Merged bugfixes from public repository"
Now you can resume your work with the bugs fixed.
The Computer Science department runs a GitLab server, and it is possible to clone the lab materials from there and import them into Mercurial: this will work even if Mike's college machine is down for some reason, such as that he has retired and gone to live in God's own county. To do this, it is necessary to have the Mercurial extension
hg-git installed and enabled. This is already done on the machines in the Software Lab, and there you can simply give the following command.
$ hg clone https://gitlab.cs.ox.ac.uk/mike/compilers.git destination directory: compilers importing git objects into hg updating to branch default 291 files updated, 0 files merged, 0 files removed, 0 files unresolved
As you see, the repository is automatically converted as it is copied. After this, everything will work the same as if you began by cloning a Mercurial repository. This method also works with the Git repository hosted at Spivey's Corner,
Of course, you can also clone these Git repositories using Git itself and interact with them that way if you prefer.
If you are using your own machine, you will have to install
hg-git first, then enable it. Installing
hg-git is typically a separate step from installing Mercurial itself; on Debian and Ubuntu, install the package
mercurial-git. Second, you must enable the extension, because it is not switched on by default. Before trying to clone the repository, create a file
.hgrc in your home directory, and in it place the following text, replacing Fred's name and e-mail address with your own.
[ui] username = Fred Bloggs <email@example.com> [extensions] hggit =
Creating this file also, naturally, sets you up to check in revisions as described earlier. For convenience, I've put a copy of this file (with Fred's name in it) at
/users/mike/hgrc.proto on the lab machines, though on those machines
hg-git is actually enabled by default.
With the options file created, you can now clone the GitLab repository.