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: Difference between revisions

From Compilers
Jump to navigation Jump to search
(4 intermediate revisions by the same user not shown)
Line 19: Line 19:
Like all commands that interact with Git, this one begins with @git@ -- the chemical symbol for Linus -- and then the name of the specific operation that is needed, in this case @clone@.
Like all commands that interact with Git, this one begins with @git@ -- the chemical symbol for Linus -- 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 clone a Git repository maintained in the Computer Science department: details [[#Using gitlab|below]].
The clone command given above depends on Mike's computer being available, and that will not be true forever.  As an alternative, you can clone a Git repository maintained in the Computer Science department:
$ <i>git clone <nowiki>https://gitlab.cs.ox.ac.uk/mike/compilers.git</nowiki></i>


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:
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:
Line 73: Line 74:


The command
The command
  $ ''hg log''
  $ ''git 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.
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==
==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
The @hg diff@ command can be used to compare any two revisions of your project or some of its files.  The simplest use is the command
  $ <i>hg diff .</i>
  $ <i>git diff .</i>
with no arguments; this compares the current directory in the working copy with the latest check-in.  Example output:
This compares the current directory in the working copy with the latest check-in.  Example output:
diff -r 13c2e7a5d54c lab2/kgen.ml
<pre>
--- a/lab2/kgen.ml Tue Jun 26 22:41:15 2012 +0100
diff --git a/lab2/kgen.ml b/lab2/kgen.ml
+++ b/lab2/kgen.ml Tue Jun 26 23:11:42 2012 +0100
index f4efc9a..b55be31 100644
\@\@ -83,11 +83,11 \@\@
--- a/lab2/kgen.ml
          gen (CALL 0)
+++ b/lab2/kgen.ml
      | IfStmt (test, thenpt, elsept) ->
@@ -69,9 +69,9 @@ let rec gen_stmt =
          let lab1 = label () and lab2 = label () in
        SEQ [CONST 0; GLOBAL "lib.newline"; PCALL 0]
-        gen_cond false lab1 test;
    | IfStmt (test, thenpt, elsept) ->
-       gen_stmt thenpt;
        let lab1 = label () and lab2 = label () and lab3 = label () in
+        gen_cond true lab1 test;
-        SEQ [gen_cond test lab1 lab2;  
+        gen_stmt elsept;
-         LABEL lab1; gen_stmt thenpt; JUMP lab3;
          gen (JUMP lab2);
-          LABEL lab2; gen_stmt elsept; LABEL lab3]
          gen (LABEL lab1);
+        SEQ [gen_cond test lab2 lab1;
-        gen_stmt elsept;
+          LABEL lab1; gen_stmt elsept; JUMP lab3;
+       gen_stmt thenpt;
+         LABEL lab2; gen_stmt thenpt; LABEL lab3]
          gen (LABEL lab2)
    | WhileStmt (test, body) ->
      | WhileStmt (test, body) ->
        let lab1 = label () and lab2 = label () and lab3 = label () in
          let lab1 = label () and lab2 = label () in
        SEQ [JUMP lab2; LABEL lab1; gen_stmt body;
</pre>
(The lines marked @-@ have been removed and replaced by those marked @+@).
(The lines marked @-@ have been removed and replaced by those marked @+@).


Also useful in the labs is the command
Also useful in the labs is the command
  $ <i>hg diff -r basis .</i>
  $ <i>git diff -r origin/basis .</i>
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.
This compares the working copy with the original source code, bookmarked as @origin/basis@, showing exactly the changes you have made.  The bookmark @origin/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==
==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.
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, and fill in some basic instructions here.
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.
$ <i>hg pull</i>
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.
$ <i>hg ci -m "Checkpoint before merging"</i>
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:
$ <i>hg merge</i>
The merged revision is now present in your working copy, and you should check it in.
$ <i>hg ci -m "Merged bugfixes from public repository"</i>
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.
<pre>
[ui]
username = Fred Bloggs <fred@bloggs.com>
 
[extensions]
hgext.git =
</pre>
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:
$ <i>hg clone <nowiki>https://gitlab.cs.ox.ac.uk/mike/compilers.git</nowiki></i>
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 [[Git cheat sheet|using Git]] and interact with them that way.

Revision as of 11:10, 15 October 2021

This page contains everything you need to know to use the Git version control system for the labs in the Compilers course. Material for the labs is provided in a public, read-only Git 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.

Cloning

The lab materials are provided in a Git repository on Mike's college computer, the same machine that hosts Spivey's Corner. To begin the labs, you should issue the command,

$ git clone http://spivey.oriel.ox.ac.uk/git/compilers.git

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 Git, this one begins with git – the chemical symbol for Linus – 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 clone a Git repository maintained in the Computer Science department:

$ git clone https://gitlab.cs.ox.ac.uk/mike/compilers.git

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/.git; 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

 $ git status

lists the files in your current directory that do not agree with the latest state of the repository. The output might look like this:

On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   kgen.ml

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	inicheck.ml

no changes added to commit (use "git add" and/or "git commit -a")

This means that the file kgen.ml has been modifed since the last check-in, and there is a file inicheck.ml that Git knows nothing about. If there are no changes since the most recent check-in, then hg st produces no output.

Checking in

If git status shows modified or new files in the current directory, then we can record these changes in the repository. It's first necessary to record the changed files in the "staging area" by giving the command

$ git add .

This will record both the changed files and the new ones so that they are committed in the next step. After this command, using git status will show the files as changes to be committed.

The files are actually committed with the command

$ git commit -m "log message"

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 Git 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).

Git records your name next to each change you check in, and that means the git commit command needs to know it. You need to create a file in your home directory called .gitconfig and in it put the following text:

[user]
name = Fred Bloggs
email = 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

$ git 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 use is the command

$ git diff .

This compares the current directory in the working copy with the latest check-in. Example output:

diff --git a/lab2/kgen.ml b/lab2/kgen.ml
index f4efc9a..b55be31 100644
--- a/lab2/kgen.ml
+++ b/lab2/kgen.ml
@@ -69,9 +69,9 @@ let rec gen_stmt =
         SEQ [CONST 0; GLOBAL "lib.newline"; PCALL 0]
     | IfStmt (test, thenpt, elsept) ->
         let lab1 = label () and lab2 = label () and lab3 = label () in
-        SEQ [gen_cond test lab1 lab2; 
-          LABEL lab1; gen_stmt thenpt; JUMP lab3;
-          LABEL lab2; gen_stmt elsept; LABEL lab3]
+        SEQ [gen_cond test lab2 lab1;
+          LABEL lab1; gen_stmt elsept; JUMP lab3;
+          LABEL lab2; gen_stmt thenpt; LABEL lab3]
     | WhileStmt (test, body) ->
         let lab1 = label () and lab2 = label () and lab3 = label () in
         SEQ [JUMP lab2; LABEL lab1; gen_stmt body; 

(The lines marked - have been removed and replaced by those marked +).

Also useful in the labs is the command

$ git diff -r origin/basis .

This compares the working copy with the original source code, bookmarked as origin/basis, showing exactly the changes you have made. The bookmark origin/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, and fill in some basic instructions here.