Information on Using RCS

Note: Read the contents of this document very carefully! You are responsible for knowing all the information contained herein, and you must follow the instructions in this document in order to complete and submit the assignments in this class.

Since this system is used only occasionally for teaching classes, this document is somewhat of a draft.


1. Introduction

RCS, the Revision Control System, is a system for managing changes to source files over the lifetime of a software project. RCS was originally developed by Walter Tichy of the Department of Computer Science at Purdue University.

The motivation for RCS is twofold: First, RCS helps multiple developers share the source files for a software project. Without RCS (or some other revision control system) in place, any user can write to any source file at any time. Even if users are extremely careful, it is still likely that bad things will happen. At some point, two users will end up editing the same file at the same time, and end up inadvertently overwriting each other's changes or corrupting the source file. RCS helps multiple developers work together by enforcing a system of file locking: you must explicitly lock a file before you may edit it. Other developers will not be able to edit the file while you have the file locked. Conversely, you will not be able to obtain a lock if the file is currently locked by someone else.

Second, RCS provides a versioning system for source files. Over the course of a development project, each source file in the project will probably be revised many times. If we aren't careful, it is very easy to make mistakes in this process, such as re-introducing a bug that was fixed in a previous release. RCS helps with this process by maintaining a complete log of all revisions to a file that are ever checked into the system, along with comments from the user about what was changed and why. RCS provides tools which make it easy to:

RCS is also a particularly useful tool for release engineering. If you are working on a multi-developer software project, and your development team has most (but not all) of the features of the product finished, you might choose to release a 1.0 version of the product. As you probably know, development does not stop once version 1.0 of the product is released. Suppose that a few months go by after version 1.0 of a product is released, and some tester finds a new bug in the latest internal development version of the source code. Suppose further that you believe that version 1.0 did not have that same bug. In order to know with certainty whether or not the bug existed in version 1.0, it would be useful to obtain a snapshot of the code for the project, as it existed on the day when version 1.0 of the product was released. RCS offers support for this through the use of labels. A label is just a string that is assigned to all source files in a project. RCS provides tools for checking out all source files which have the same label. This makes it possible to obtain exactly the kind of "snapshot" of the source code that is needed for release engineering.

In our use of RCS, we will use a script called rcssubmit to submit assignments. This script makes use of the label facility of RCS to take a consistent snapshot of your group's RCS tree. This snapshot of your work is then "released" to a directory tree accessible by the T.A., just as if you you were releasing a version of a real product. Of course, you may continue to revise the source files as you work on subsequent assignments, without fear that your changes will have any adverse effect on the snapshot of source files that you submitted.


2. Linking to your group's RCS repository

We have already created, for each group, an RCS repository that contains a fresh version of all of the Nachos source files. We have also written a shell script, rcsinit that makes it easy to set up your own work area (called a 'sandbox') that is shared with the other members of your group. In order to set up your environment, and construct your sandbox, you must do the following:
  1. Add the class bin directory to your PATH

    In addition to the rcs utilities that are already pre-installed on the Zoo, you will also need run a few shell scripts that we have written. Because some of these scripts invoke others of these scripts, it is necessary that the directory containing these scripts be added to your PATH environment variable.

    The details of adding a the class bin directory to your path are shell-specific. Here are instructions for two of the most common shells. (If you know enough to have changed your shell to one that is not listed here, then hopefully you also already know how to add items to your PATH.)

    If you are using csh:

    The default shell on the Zoo is tcsh. If you are using the C shell (csh), or one of its derivatives (such as tcsh), you should use your favorite text editor to add the following line to your ~/.cshrc file:
    set path=(/c/cs422/bin $path)
    

    If you are using bash:

    If you are using bash (the preferred shell of all Linux hackers :-) ), you should use your favorite text editor to add the following to your ~/.bashrc:
    PATH=/c/cs422/bin:$PATH
    

  2. Logout and login again.

    After adding the class bin directory to your PATH, you should logout and log back in again to ensure that the change has taken effect.

  3. Run rcsinit

    To get you started using RCS, we have written a shell script which will set up a 'sandbox' in which you can do your development work on Nachos. A 'sandbox' is a private directory tree in which you can do your own programming work, but which is linked to the RCS repository shared with the rest of your group members.

    By now, you should have filled out an on-line web page to sign up for this class and obtain disk space for working on class projects. (If not, then you should go here and fill out the appropriate form right away). As a result of signing up for the class, you should have a directory (really a symbolic link) in your home directory named 'cs422', in which you can keep your work for this class.

    To set up your sandbox, you should:

    If all goes well, rcsinit should print a message indicating that it completed succesfully.

    This 'sandbox' is a directory tree which has exactly the same structure as the nachos 'code' subdirectory. Within each subdirectory in the tree, there will be a file called RCS that is a symbolic link to the master RCS repository that you share with the rest of your group members. As you work, you will use special RCS commands which access the shared RCS repository through these symbolic links.

  4. Try it out!

    After running rcsinit, you will have your own sandbox in which to work. After building all of the links to the group's RCS repository, rcsinit also "checks out" a private, read-only copy of each of the source files.

    To make sure that rcsinit did its job correctly, you can do a build of the nachos source tree in your sandbox. Do the following:

    % cd code
    % make
    

    If all goes well, this will build the nachos source tree. After a few seconds of compilation, you should (among other things) have an executable file 'nachos' in the subdirectory 'threads'.


3. How you should use RCS

This section provides enough information about RCS to get you started. For more detailed information, you should consult the various man pages for the RCS commands. The man page rcsintro(1) is a good place to start.

3.1 co

The command co is used to "check out" a copy of a file from RCS. There are three basic forms that you should know about:
  1. To get the most recently checked-in copy of a file:

    Suppose that one of the members of your group (other than you) has been editing a file (list.cc, say) in her own sandbox, has fixed a bug, and has "checked in" the change to RCS. If you simply want to obtain your own copy of that particular source file, you can run the command:

    % co list.cc
    RCS/list.cc,v  -->  list.cc
    revision 1.1
    done
    
  2. To lock a file for editing:

    The model that RCS uses (by default) is that you must lock a file before you can edit it. If you look at the file permissions of a file that has been checked out (but not locked) you will see that the file permissions have been set to read-only by co, to prevent you from inadvertently editing the file. For example, if we run ls on the file from the previous example, we will see something like the following:

    % ls -l list.cc
    -r--r--r--   1 aac28    cs422g4      7143 Jan 25 08:48 list.cc
    %
    
    In order to check out a file for editing, you must run co with the -l option, to lock the file:
    % co -l list.cc
    RCS/list.cc,v  -->  list.cc
    revision 1.1 (locked)
    done
    
    Now when we run ls, we see that the file is writeable:
    % ls -l list.cc
    -rw-r--r--   1 aac28    aac28        7143 Jan 25 23:00 list.cc
    % 
    
  3. To update a directory with the latest checked-in versions of all files:

    To update a directory with the latest copies of all files in that directory that are checked in to RCS, you should run the following command:

    % co RCS/*
    
    This will update all source files in the current directory to their latest versions. Co is careful about checking file permissions, so it will prompt you before overwriting any files that you are currently editing.

    This form is also the easiest way to obtain copies of files that have been added to the directory by your team members. Since this command is robust (in the sense that it will never overwrite files you are editing), you should run it often to keep yourself "in sync" with the rest of your group members.

    Note that this only checks out all files for the current directory, and does not recurse into subdirectories. So you will need to re-run this command in every directory that you wish to have updated. (If you are feeling like a good citizen, you could write a simple shell script 'rcsupdate' to do this recursively. If you do so, please contact the T.A., who will make it available for others.)

3.2 ci

The ci command is used to "check in" files to RCS. There are two reasons to use the ci command:
  1. To check in changes you made to a file you have checked out:

    If you have checked out a file for editing, and have finished editing it, and have tested your changes, then you should run ci to check the file back in to RCS:

    % ci list.cc
    RCS/list.cc,v  <--  list.cc
    new revision: 1.2; previous revision: 1.1
    enter log message, terminated with single '.' or end of file:
    >> Added support for iterators by adding GetIterator() method.
    >> .
    done
    %
    
    As you can see, ci will prompt you for a log message that is stored with the file. You should always include a log message that gives a short, concise summary of what you have changed. One line is usually sufficient.

  2. To add a new source file to the RCS repository:

    If you have created a new source file, then you will need to place this file under RCS control. To do so, simply run ci on the new source file. For example, if we created a file "listiterator.cc" that we wished to add to the repository, we would do so as follows:

    % ci listiterator.cc 
    RCS/listiterator.cc,v  <--  listiterator.cc
    enter description, terminated with single '.' or end of file:
    NOTE: This is NOT the log message!
    >> An implementation of Iterator design pattern for iterating over lists.
    >> .
    initial revision: 1.1
    done
    %
    
    This time we were prompted for a description of the source file being added. Note that other members of your group can obtain a copy of the new source file you just added by changing to the appropriate directory on their sandbox, and running the command co RCS/*.

3.3 rcstell

The command rcstell is a useful utility script we have provided for your benefit. When invoked, rcstell will give you a complete list of any files checked out by any users in the current directory or any subdirectories of the curent directory. For example, here is the output of running rcstell in the top-level 'code' directory of my sandbox:
% rcstell
Files checked out in ./filesys/test:
 Working file: big revision 1.1 locked by: aac28

Files checked out in .:
 Working file: Makefile revision 1.1 locked by: aac28
 Working file: Makefile.dep revision 1.1 locked by: aac28
%

The command rcssubmit (described in the next section) which you will use to submit assignments only submits the versions of files that are checked in to RCS. You can use rcstell in the top-level directory of your sandbox to make sure that everything you wish to submit is checked in.

3.4 rlog

The command rlog gives you detailed log information about a particular file or files. You can use this to, for example, examine the revision history of a particular file, or to view the comments associated with each check-in.

The basic forms of rlog you will need are:

The information displayed by rlog is somewhat voluminuous, and rlog only works on a single directory. This is why we have provided you with the rcstell command, which is really just a wrapper that invokes rlog to do its work. You should consult the UNIX man page rlog(1) for more information.


4. Submitting Assignments with rcssubmit

4.1 rcssubmit

To submit an assignment, we have provided a shell script which will:

Before you run rcssubmit, you should:

  1. Make sure you are in the top-level 'code' directory of your sandbox.

    If you followed the instructions given here on setting up your sandbox, this should just be the directory ~/cs422/code.

  2. Make sure that none of your teammates has already run rcssubmit for this assignment.

    Since rcssubmit works on the RCS repository that you share with your teammates, there is no need to run rcssubmit more than once per assignment per group. If you aren't sure if your teammate have already run rcssubmit, you can use rcscheck to check.

  3. Make sure that the versions of all source files that you wish to submit are checked in to RCS.

    You can do this by running rcstell from your 'code' directory. If rcstell is silent, then you are in good shape. Finally, you are ready to run rcssubmit. To do so, just type:

    rcssubmit N

    where N is the assignment number you wish to submit (1-4).

    4.2 rcscheck

    You can use the utility rcscheck to check if you or any of your teammates have submitted an assignment. To do so, simply type:

    rcscheck N

    where N is the assignment number you wish to check.


    5. Some Basic DOs and DON'Ts of RCS

    RCS is a useful tool for software development. But, like most UNIX tools, it is only useful if you play by the rules. Here are a few guidelines that will help you use RCS effectively. Failure to follow these rules will cause you no end of grief and hardship.

    Note that the last two suggestions are somewhat conflicting: you should try to minimize the length of time you have a file locked, but you should also test before checking in, which takes time. The best way to deal with this problem is with careful design. If you do careful design work before you start editing, then you will minimize how long it takes you to make your modifications. And you should understand how to test your design, so that you can minimize the length of time it takes to test your changes.
    Copyright (c) 1999 - 2000, Antony Courtney, Dept. of Computer Science, Yale University.