Since this system is used only occasionally for teaching classes, this document is somewhat of a draft.
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
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.
rcsinitthat 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:
bindirectory to your
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
set path=(/c/cs422/bin $path)
:-)), you should use your favorite text editor to add the following to your
After adding the class bin directory to your
should logout and log back in again to ensure that the change has
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:
% cd ~/cs422
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.
rcsinit, you will have your own sandbox in
which to work. After building all of the links to the group's RCS
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
% 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'.
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.
cois used to "check out" a copy of a file from RCS. There are three basic forms that you should know about:
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
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
prevent you from inadvertently editing the file. For example, if we
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
-loption, to lock the file:
% co -l list.cc RCS/list.cc,v --> list.cc revision 1.1 (locked) doneNow 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 %
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.
Cois 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.)
cicommand is used to "check in" files to RCS. There are two reasons to use the
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,
ciwill 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.
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
rcstellis a useful utility script we have provided for your benefit. When invoked,
rcstellwill 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
rcstellin 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 %
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.
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:
rlogwill display log information for the given source file in the current working directory.
rlog RCS/*will display log information for all source files checked in this directory.
The information displayed by
rlog is somewhat
rlog only works on a single directory.
This is why we have provided you with the
command, which is really just a wrapper that invokes
to do its work. You should consult the UNIX man page
rlog(1) for more information.
To submit an assignment, we have provided a shell script which will:
Before you run
rcssubmit, you should:
If you followed the instructions given here on setting up your
sandbox, this should just be the
rcssubmitfor this assignment.
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.
You can do this by running
rcstell from your 'code'
rcstell is silent, then you are in good
Finally, you are ready to run
rcssubmit. To do so, just
where N is the assignment number you wish to submit (1-4).
You can use the utility
rcscheck to check if you or any
of your teammates have submitted an assignment. To do so, simply
where N is the assignment number you wish to check.
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.
The RCS commands
ci use file
permissions to enforce locking. If a file is checked out for editing
(locked) by someone else, then you should not edit the file!
Find out who has the file locked (using
communicate with them in person or in email to request that they
either unlock the file for check in their changes.
A good editor (i.e.
emacs) will not let you edit a file
for which you do not have
write permission. However, if you are using a particularly primitive
text editor (
vi), and you ignore its warning message, you
might end up inadvertently editing a file that you do not have checked
out for editing. If this unfortunate case should arise, you should do
diffto help you figure out what changes you made.
co -lto check out a file for editing before modifying it.
rcsinit more than once.
You will only need a single sandbox in which to edit source code and perform compilations. And you will only need to set up this sandbox once for the entire semester.
rcscheck from anywhere other
than your top-level 'code' directory.
rcssubmit works by assigning a label to the
files checked in to RCS in the current directory and all
subdirectories. In order to ensure that the source code that you
submit will build properly when the T.A. grades your work, you must
take a snapshot of the complete
source tree. Running
rcssubmit from the top-level 'code'
directory of your sandbox will ensure this.
Since you share the RCS repository with your group, only one of you needs to submit per group.
rcstell before running
rcssubmit can only label the versions of files that
are currently checked in to RCS. You should run
rcssubmit to be sure that you know which
files are currently being edited.
In general, you will want all files to be checked in by all
members of your group before running
rcssubmit. In this
rcstell will produce no output. The only times that
you might want run
rcssubmit with a file checked out for
editing (locked) is if you or one of your teammates has already
started work on the next assignment before submitting the current
assignment , or if one of you is working on a bug fix for the current
assignment that you do not wish to submit. Note that both of these
circumstances are extremely unlikely.
In general, if you find that
rcstell indicates that files
are locked, you should communicate with your team members to get the
files checked in before running
RCS is designed to help manage source files that are written and edited by a warm human. RCS uses file permissions to enforce locking and ensure that aforementioned warm humans do not make mistakes.
On the other hand, compilers and related tools read source files and produce their output by writing object files. Obviously, the files produced by a compiler (or other tool, such as makedepend) must get overwritten every time the compiler or tool is invoked. This requires that the object file be writeable any time the compiler or tool is run, or the compiler will produce an error message.
In addition to creating annoying error messages that are difficult to fix, it is absolutely useless to check in object files or derived files to RCS, since they can always be re-created from their corresponding sources. Therefore, you should be very careful not to add any files to the RCS repository other than files that you personally created.
This will help you avoid annoying your teammates, who may also need to edit the same files.
This is an application of the Golden Rule. If you do not test your changes before checking in a file, and your file has bugs, then when your teammates check out the file, their build will have bugs. To avoid this kind of egregiously anti-social behavior, you should test your changes thoroughly before doing a check-in.