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.
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:
obtain an earlier revision of a source file,
examine the log of changes,
compare the current version of a file with a previous revision,
and
discard un-commited changes to a source file, and revert to a
previous revision.
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.
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:
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
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.
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:
Change your current directory to your cs422 directory:
% cd ~/cs422
Run the rcsinit command:
% rcsinit
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.
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'.
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:
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
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:
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
%
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:
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.
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:
rlog ...
will 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
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.
To submit an assignment, we have provided a shell script which will:
Use RCS to assign a consistent label to all of the source files in your source tree.
Build a 'sandbox' in the class directory from the labelled tree
that the T.A. can use to grade your assignment.
Before you run rcssubmit, you should:
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.
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.
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:
rcssubmitN
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:
rcscheckN
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.
DO NOT: circumvent RCS locking by modifying file permissions!
The RCS commands co and 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 rcstell), and
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
the following:
save your work to a temporary file with a different name,
check out the file for editing (using co -l),
manually merge your changes from the temporary file into
the checked out file. You can use diff to help you
figure out what changes you made.
But the best advice is to avoid this situation in the first place by
always running co -l to check out a file for editing
before modifying it.
DO NOT: run 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.
DO NOT: run rcssubmit or
rcscheck from anywhere other
than your top-level 'code' directory.
The script 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.
DO: Elect a single person from your team to run rcssubmit.
Since you share the RCS repository with your group, only one of you
needs to submit per group.
DO: run rcstell before running rcssubmit.
Remember that rcssubmit can only label the versions of files that
are currently checked in to RCS. You should run rcstell
before running 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
case, 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 rcssubmit.
DO NOT: check binaries, object files, backup files, or any
other
derived
file into RCS.
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.
DO: strive to only lock files when you are going to edit
them.
This will help you avoid annoying your teammates, who may also need to
edit the same files.
DO: test your changes before checking in a file.
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.
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.