[Kernel, courtesy IowaFarmer.com CornCam]

Readable Kernel Systems, Winter 2005

Using CVS

As the class goes on, we're going to release multiple versions of JOS. Here's how to use CVS (the Concurrent Versions System, a source code management system) to keep up to date with our code base. There are many other ways, of course, including running diff and patch by hand; using the make patch procedure from the Advanced OS class; and using another source code management system.

Our CVS instructions are based in part on "Tracking Third-Party Sources", part of the useful CVS manual. On most Unix systems you can access this manual with info cvs, or from within Emacs's info pages.

CVS Concepts

The two fundamental CVS concepts are a repository and working copies. The repository holds a permanent historical record of changes made to your project files. A working copy is a snapshot of the project files; only working copies are directly editable. To make a change to a project, you check out the project, make your change to that working copy, and then commit your changes. This adds your changes to the repository, so that other people can see them.

Creating a Repository

First, then, we need to create a repository. We'll make a remote repository accessible over ssh, so that everyone on your team can access it. Tell CVS that you plan to use ssh to access remote repositories:

bash-type shells:                 tcsh-type shells:
% export CVS_RSH=ssh              % setenv CVS_RSH ssh

You'll probably want to add this to your ~/.bashrc or ~/.tcshrc so it happens automatically when you log in. Also, consider creating a ~/.cvsrc file so you don't have to type common options over and over again. For instance:

cvs -z5
update -P -d
diff -u

These options tell CVS to compress network traffic, which can make things a lot faster (-z5); to prune empty directories and add new directories during updates (-P -d); and to use the unified diff format by default (-u).

Choose a computer system that everyone on your team can log in to over ssh, and choose a directory to hold your repository. Good directory choices might be someone's ~/cvsroot or ~/jos-cvsroot. We'll call the system fun.cs.ucla.edu and the directory /home/jos/cvsroot. Now, make that directory:

% ssh fun.cs.ucla.edu
Last login: ...
Welcome to fun.cs.ucla.edu!
% mkdir /home/jos/cvsroot

We now need to make sure that everyone on your team can access the directory. Hopefully, everyone is part of the same Unix group, like users or something; we'll assume group josheads. Then run:

% chgrp josheads /home/jos/cvsroot
% chown g+rws /home/jos/cvsroot
     # The 's' means subdirectories will get group josheads automatically.

(If there's no shared group, you'll have to make the repository world-writable.) Finally, the cvs init command will set up the directory as a repository. We'll run this command remotely:

% cvs -d fun.cs.ucla.edu:/home/jos/cvsroot init

(The -d global option, which must come before the subcommand, here "init", tells CVS where to find the repository.)

Importing JOS

Now we have an empty repository; our next step is to add JOS. Download jos.tar.gz and run the following commands:

% tar xzf jos.tar.gz      # or 'gzcat jos.tar.gz | tar xf -'
% cd jos
% cvs -d fun.cs.ucla.edu:/home/jos/cvsroot import \
         -ko -m 'Initial checkin' jos-rks JOSDIST REL_1

This will import JOS into the repository, under the module name jos-rks (of course, you can pick your own module name). The other two arguments are the vendor branch JOSDIST, and the release tag REL_1; we'll use those to keep up to date with new JOS releases. The -ko option tells CVS not to expand RCS-style keywords like $Id:. The -m option supplies a checkin message; without -m, CVS will open an editor for you to enter a checkin message.

Making Changes

Now it's easy to get a working copy:

% cd ~
% cvs -d fun.cs.ucla.edu:/home/jos/cvsroot co jos-rks
% ls ~/jos-rks
CODING  GNUmakefile  conf  grade.sh  kern  mergedep.pl
CVS     boot         fs    inc       lib   user

Within the jos-rks directory, you can use simple commands like cvs ci to commit your local changes to the repository; cvs up to update your working copy with other people's changes; cvs add to add files to the repository; cvs rm to remove files; and cvs diff and cvs annotate to investigate file history. Note that none of these commands require a "-d fun.cs.ucla.edu:/home/jos/cvsroot" argument, since that information is stored in the working copy's CVS subdirectories.

Updating JOS

Finally, here's how to merge in changes from a new jos.tar.gz release. Basically, you'll just run cvs import again, but with a new "release tag" (not REL_1). So first find out what release tags currently exist, using the cvs log command in your working copy. For example:

% cd ~/jos-rks
% cvs log -rJOSDIST. -h GNUmakefile

RCS file: /home/jos/cvsroot/jos-rks/GNUmakefile,v
Working file: GNUmakefile
head: 1.1
branch: 1.1.1
locks: strict
access list:
symbolic names:
        REL_2: 1.1.1.1
        REL_1: 1.1.1.1
        JOSDIST: 1.1.1
keyword substitution: o
total revisions: 2
=============================================================================

The -rJOSDIST. option tells cvs log to report revisions from the JOSDIST branch, which only includes imports. The -h option leaves off any log messages. Take a look at the "symbolic names" section. The latest release tag checked in is REL_2 (in red), so we'll use REL_3 for our import.

Now download the new jos.tar.gz and import it with that tag.

% tar xzf jos.tar.gz
% cd jos
% cvs -d fun.cs.ucla.edu:/home/jos/cvsroot import \
         -ko -m 'new release' jos-rks JOSDIST REL_3
...

If all goes well, the import will succeed completely, but you might see a message like this:

2 conflicts created by this import.
Use the following command to help the merge:

        cvs checkout -jJOSDIST:yesterday -jJOSDIST jos-rks

This means you've locally modified some files that were also modified in the newest jos.tar.gz release. No problem! But don't run the command suggested by CVS; instead, use specific release tags, like this:

% cd ~
% ls jos-rks    # Already a working directory there
CODING  GNUmakefile  conf  grade.sh  kern  mergedep.pl
CVS     boot         fs    inc       lib   user
% cvs -d fun.cs.ucla.edu:/home/jos/cvsroot co -jREL_2 -jREL_3 jos-rks

The last command checks out the differences between the last two releases, REL_2 and REL_3, and merges them into the working directory. Then:

% cd jos-rks
% cvs up
... files modified between REL_2 and REL_3 will show up as 'M'odified ...
... if there are 'C'onflicts, resolve them by editing the relevant files ...
% cvs ci -m 'merge changes from new jos.tar.gz release'

And you're all set.

Wrapup

For more CVS information, see the CVS manual, or one of the CVS books available. Feel free, of course, to send mail with any questions.

Back to Advanced Operating Systems, Fall 2004