Note: I've just migrated to a different physical server to run Spivey's Corner,
with a new architecture, a new operating system, a new version of PHP, and an updated version of MediaWiki.
Please let me know if anything needs adjustment! – Mike

Git cheat sheet

From Compilers
Revision as of 14:22, 14 October 2021 by Mike (talk | contribs)
Jump to navigation Jump to search

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.

Cloning

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 clone.

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

The directory 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.

Showing status

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.ml, kgen.ml~ and 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 changed since the most recent check-in, then hg st produces no output.

Checking in

If 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 <fred@bloggs.com>

(substituting, of course, your real name and e-mail address for the strings Fred Bloggs and fred@bloggs.com). 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 ls -a.

Viewing logs

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.

Diff listings

The 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.

Using gitlab

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 follow this route, several stages are needed.

First, you must have the Mercurial extension hg-git installed. This is automatic with recent versions of Mercurial (from 5.0 on, I think), but on older versions, you must install it separately. On Debian Buster, 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 <fred@bloggs.com>

[extensions]
hgext.git =

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.

With the options file created, you can now clone the CS repository:

$ 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,

https://spivey.oriel.ox.ac.uk/git/compilers.git

Of course, you can also clone these Git repositories using Git and interact with them that way.