CVS


Table of Contents

1. Introduction
2. CVS Basics
2.1. CVS Basics Introduction
2.2. Installation
2.3. CVSROOT
2.4. Import: Setup a new project
2.5. Checkout
2.6. Remove
2.7. Add
2.8. Commit
2.9. Update
2.10. Diff
2.11. Other commands
3. Accessing A Remote Repository
4. Setting Up A CVS Server
5. Survival Guide For BHAM CS Students
5.1. Phase 1: Setting up your Repository
5.2. Preparing to Import a Project
5.3. Importing and getting started
5.4. Problems
5.4.1. Disk Space
5.4.2. Repairing the damage
6. References (And Links You May Find Useful)

CVS(Concurrent Versioning System) is a version control system designed to assist in the production of multi-person concurrent access software projects, the official CVS home page is http://www.gnu.org/software/cvs/cvs.html. CVS is used to manage the access of software projects.

There are chapters of the book Open Source Development with CVS by Karl Fogel available online at http://cvsbook.red-bean.com, you can even download the free chapters for viewing offline. This is more than adequate for any user wanting to use CVS, beginners and experienced alike. I will not try and replicate what can be found elsewhere, especially when what can be found elsewhere is totally sufficient. If this guide is not enough for you, go read the the one mentioned. If you don't have the Internet, or even have access to the Internet, I do not believe you, there are Internet cafes all over the world, and I doubt there is any University out there without an Internet connection.

The canonical reference for CVS is Version Management with CVS by Per Cederqvist et al known as "The Cederqvist" after it's author. Another excellent CVS resource is The CVS Book by Karl Fogel, it can be found at http://cvsbook.red-bean.com/.

This next few sections should be read sequentially because each section has dependencies on the last (apart from the first of course, which has no last, ;) ). For reference, it has been organised into sections that should be sufficient to illustrate how a command is used on it's own, independent of the dependencies.

In order to use the tools we are about to install it is necessary to setup the operating environment so that the tools know where to find stuff they need and the operating system knows where to find the tools. A understanding of how to do this is essential as you will be asked to change the operating environment. I have comprehensively covered this in documents entitled Configuring A Windows Working Environment and Configuring A Unix Working Environment.

If you are using a Unix system it is likely that CVS is already installed, test this by executing:

cvs --version

If you get no output, CVS is not installed, download and install it from http://ccvs.cvshome.org/servlets/ProjectDownloadList.

If you are a Windows user you can download the CVS binaries from here: http://www.cvshome.org/dev/codewindow.html, take notice of the description of the binaries offered on the web page. You will not be able to setup a CVS server on a Windows box unless you are willing to tryout experimental software. You will only be able to setup a local repository and be able to checkout remote projects. The zip file available on this page contains the single file cvs.exe, place this in one of the directories listed in your PATH.

To use SSH with CVS it is necessary set the CVS_RSH to ssh. Users will therefore require a working ssh binary, on Unix this is most likely already setup, if you are using Windows see http://www.mindon.net/illinar/studio/cvs/win.html.

The import option allows one to import files into a project, this is usually done right at the beginning of a project. The import command takes the form:

import [options] repository vendor-tag release-tags... 
Import files into CVS, using vendor branches.
-b bra
Import to vendor branch bra.
-d
Use the file's modification time as the time of import.
-k kflag
Set default keyword substitution mode.
-m msg
Use msg for log message.
-I ign
More files to ignore (! to reset).
-W spec
More wrappers.
      

The usual way to setup a project is to cd to the directory which contains the project and type:

cvs import  -m "Initial CVS Import" ProjectName MySoftwareCompany Start

The more generic form is:

cvs import [-m msg] repository vendor-tag release-tags

The -m option indicates a message that will accompany this import. The last two options are obligatory and are mainly concerned with the importation of previous projects to CVS. Set the first option of these two to the name of your software company (or whatever) and set the second option of these two to "start", to indicate that this is the start of the project. When the command is executed, CVS will add a new project to the CVS repository; the project you just imported, the initial release value will be set to 1.1.1.1 which is how CVS specifies that this is the very first release, you should see a confirmation message similar to the following:

cvs import: Importing ${CVSROOT}/ProjectName/
N ProjectName/Main.java
N ProjectName/ExitControl.java
N ProjectName/numbers
N ProjectName/text

No conflicts created by this import.
      

Indicating that the project has been successfully imported into the CVS repository, the preceding 'N' on each line indicates a Newfile. If you get errors make sure that the CVSROOT environment variable is setup and that the CVS repository has been correctly initiated.

Create a directory in some temporary location called chemlink and create a file in it called chemlink.java containing:

public class Chemlink {
   public static void main(String[] args) {
      System.out.println("Welcome To ChemLink!");
   }
}        
      

Make a new directory called images and create an empty file in it called oxygen.png, you should have the following directory (and file) tree:

/path/to/temp/chemlink/
/path/to/temp/chemlink/chemlink.java
/path/to/temp/chemlink/images/
/path/to/temp/chemlink/images/oxygen.png
      

Import the project into CVS like this:

        cvs import -m "Initial Import - Chemistry Project" chem MySoftwareCompany start
      

You should see the project imported correctly:

N chem/Chemlink.java
cvs import: Importing /usr/local/cvs/chem/images
N chem/images/oxygen.png

No conflicts created by this import
      

This will create a new directory in the location specified by CVSROOT called chemlink. It will contain the files:

.:
Chemlink.java,v
d
images

./images:
oxygen.png,v
      

Notice the files that end in ",v", these are the files used by CVS to keep track of the status of the individual files of the project. Let's take a look at the file Chemlink.java,v:

head     1.1;
branch   1.1.1;
access   ;
symbols  start:1.1.1.1 MySoftwareCompany:1.1.1;
locks    ; strict;
comment  @# @;


1.1
date     2002.08.13.10.38.22;  author YourUserName;  state Exp;
branches 1.1.1.1;
next     ;

1.1.1.1
date     2002.08.13.10.38.22;  author YourUserName;  state Exp;
branches ;
next     ;


desc
@@



1.1
log
@Initial revision
@
text
@public class Chemlink {
   public static void main(String[] args) { 
      System.out.println("Welcome To ChemLink!");
   }
}
@


1.1.1.1
log
@Intial Import - Chemistry Project
@
text
@@
      

It contains information about the current release as well as the actual content of the file it represents. CVS will only have one ",v" file for each file in your project. When you checkout a copy of the file, you will get a copy of the latest release, this will be the actual file, not the ",v" file. When you check your copy back in, any changes will be reflected in the "v" file, hence CVS can keep a history of every little change made to each file so that one can, for instance, go back to previous versions if the current version is broken.

Once you have created your new project (or have decided you would like to checkout an already existing project), you will have to checkout the project so that you can modify it. The command synopsis for checkout is:

checkout [options] modules... 
Get a copy of the sources. 
-A 
Reset any sticky tags/date/options. 
-c 
Output the module database. 
-D date 
Check out revisions as of date (is sticky). 
-d dir 
Check out into dir. 
-f 
Use head revision if tag/date not found. 
-j rev 
Merge in changes. 
-k kflag 
Use kflag keyword expansion. 
-l 
Local; run only in current working directory. 
-N 
Don't "shorten" module paths if -d specified. 
-n 
Do not run module program (if any). 
-P 
Prune empty directories. 
-p 
Check out files to standard output (avoids stickiness). 
-R 
Operate recursively (default). 
-r tag 
Checkout revision tag (is sticky). 
-s 
Like -c, but include module status. 
      

Assume we want to access some project named chem, (which was described in the last section). Make a directory called user1 and go into it. The project is checked out like this:

cvs co chem

More generically:

cvs co ProjectName

The option co is just a shortcut for checkout, and is legacy from the days of RCS. This will checkout all the files in the project or module specified, in this case, all the files contained in the chem project, to the directory current directory, all necessary subdirectories will be created. The output generated when the above command sequence is executed is:

cvs checkout: Updating chem
cvs checkout: Updating chem
U chem/Chemlink.java
cvs checkout: Updating chem/images
U chem/images/oxygen.png
      

U is for Update. The output indicates that everything has occurred successfully and every file in the project has been checked out. These files can be edited as much as is required.

The remove option removes files from the repository:

remove [options] [files...] 
Remove an entry from the repository. 
-f 
Delete the file before removing it. 
-l 
Local; run only in current working directory. 
-R 
Operate recursively (default). 
      

If there is a file in the project that is no longer used, you may wish to remove it, this can be achieved like this:

        cvs remove File.Extension
      

Causing the output:

cvs remove: scheduling 'File.Extension' for removal
cvs remove: use 'cvs commit' to remove this file permanently
      

The add option adds files to the project:

add [options] [files...] 
Add a new file/directory. 
-k kflag 
Set keyword expansion. 
-m msg 
Set file description. 
      

This will be illustrated by adding a new file to the chemlink project. Create an empty file called ChemElectrovalence.java and add it to the project like this:

        cvs add -m "Electrovalent bond simulation module" ChemElectrovalence.java
      

You will be given the following in reply:

cvs add: scheduling file `ChemElectrovalence.java' for addition
cvs add: use 'cvs commit' to add this file permanently.
      

After you have done whatever you wanted to do with the files, if you have edited them, it is assumed you will want to commit your changes to the repository. Here is the synopsis for the commit option:

commit [options] [files...] 
Check changes into the repository. 
-F file 
Read log message from file. 
-f 
Force the file to be committed; disables recursion. 
-l 
Local; run only in current working directory. 
-m msg 
Use msg as log message. 
-n 
Do not run module program (if any). 
-R 
Operate recursively (default). 
-r rev 
Commit to rev. 
     

In the previous section some changes were made, let's commit them:

cvs commit

CVS will prompt you to enter a message to be used enter one. This will cause CVS to output the messages:

cvs commit: Examining .
cvs commit: Examining images
RCS file: /usr/local/cvs/chem/ChemElectrovalence.java,v <-- ChemElectrovalence.java
initial revision: 1.1
done
     
[Note]Note

One may also use the pseudonym ci which stands for check in and is legacy left over from the days of RCS(Revision Control System) upon which CVS is based upon and uses.

The update option is used to bring your checked out version of the project upto date with any changes other users may have made since you checked out your copy. In order to simulate this we will trick the CVS system into believing that somebody else has been messing with the project.

cd to the base of the working directory that you originally checked out the project from. Create a directory called user2 and cd into it. Checkout a new copy of the project for user2:

        cvs co chem
      

Edit this copy of Chemlink.java and add the line:

System.out.println("It's the best!");
      

After the other print statement and commit the changes like so:

        cvs commit -m "Added a line to Chemlink.java"
      

This will cause CVS to output:

cvs commit: Examining .
cvs commit: Examining images
Checking in Chemlink.java
/user/local/cvs/chemlink/chemlink/Chemlink.java,v <-- Chemlink.java
new revision: 1.2; previous revision: 1.1
done
      

Notice that the revision has been incremented, this has nothing to do with the actual version of the program it is just a number used internally by CVS. To illustrate this, change the second line to:

System.out.println("It is really good!");
      

And commit again, this will cause CVS to output the message:

cvs commit: Examining .
cvs commit: Examining images
Checking in Chemlink.java;
/usr/local/cvs/chem/Chemlink.java,v <-- Chemlink.java
new revision: 1.3; previous revision: 1.2
done
      

cd to user1's directory and take a look at the file Chemlink.java. The file has not been updated with the modifications user2 made, this is what it looks like:

public class Chemlink {
   public static void main(String[] args) {
      System.out.println("Welcome To ChemLink!");
   }
}
      

update is used to bring these modifications in to this copy of the project:

cvs update

This will cause CVS to produce the output:

cvs update: Updating .
U Chemlink.java
cvs update: Updating images 
      

Notice the 'U' signifying that Chemlink.java was updated in the process. This copy of Chemlink.java now looks like:

public class Chemlink {
   public static void main(String[] args) {
      System.out.println("Welcome To ChemLink!");
      System.out.println("It is really good!");
   }
}
      

Notice that it has imported the changes submitted by user2. To make things a little more interesting let's add our own changes to the file. Edit Chemlink.java and, between the other print statements, add the line:

System.out.println("It is fantastic!");
      

cd to user2's directory and edit his copy of Chemlink.java, between the two print statements, add the line:

        System.out.println("It is perfect!");
      

Commit the changes:

        cvs commit -m "Added another intro msg""
      

CVS outputs:

cvs commit: Examining .
cvs commit: Examining images
Checking in Chemlink.java;
/usr/local/cvs/chem/Chemlink.java,v  <-- Chemlink.java
new revision: 1.4; previous revision: 1.3
done
      

Everything is now set up to create a conflict. cd user1's directory out version and commit user1's changes:

        cvs commit -m "Added another intro msg""
      

CVS outputs:

cvs commit: Examining .
cvs commit: Up-to-date check failed for `Chemlink.java'
cvs commit: Examining images
cvs [commit aborted]: correct above errors first!
      

Indicating that this copy of Chemlink.java is not up-to-date, and that update must be called before committing:

        cvs update
      

CVS outputs:

cvs update: Updating .
RCS file: /usr/local/cvs/chem/Chemlink.java,v
retrieving revision 1.3
retrieving revision 1.4
Merging differences between 1.3 and 1.4 into Chemlink.java
rcsmerge: warning: conflicts during merge
cvs update: conflicts found in Chemlink.java
C Chemlink.java
cvs update: Updating images
      

Conflicts have been found in the file Chemlink.java, hence the capital C for conflict before the filename Chemlink.java. These conflicts have to be resolved before CVS will allow a commit. The merged Chemlink.java file looks like this:

public class Chemlink {
   public static void main(String[] args) {
      System.out.println("Welcome To Chemlink!");
<<<<<<< Chemlink.java
      System.out.println("It is fantastic!");
=======
      System.out.println("It is perfect!");
>>>>>>> 1.4
      System.out.println("It is really good!");
   }
}        
      

The content after the line of '<' is the content that the user that called the update has in his file and the content after the line of '=' is the content that is in the repository copy that is conflicting. At this point it is up-to the people editing the documents to decide how to the resolve the conflict, this may not require actually speaking to the person as it may just be a case of rearranging the text. Assume that some discussion has occurred and the result is that the line "It is perfect!" should be removed, edit Chemlink.java and remove the unwanted line:

public class Chemlink {
   public static void main(String[] args) {
      System.out.println("Welcome To Chemlink!");
      System.out.println("It is fantastic!");
      System.out.println("It is really good!");
   }
}
      

Call update again and CVS outputs the following:

cvs update: Updating .
M Chemlink.java
cvs update: updating images
      

The file Chemlink.java has been modified, indicated by the prefixed M. Commit the changes:

        cvs commit -m "Removed an unwanted message"
      

The response is:

cvs commit: Examining .
cvs commit: Examining images
Checking in Chemlink.java;
/usr/local/cvs/chem/Chemlink.java,v <-- Chemlink.java
new revision: 1.5; previous revision: 1.4
done
      

The conflict has been resolved.

Sometimes one wants to see how a currently checked out version of a file differs from the corresponding file in the repository, this is achieved using the diff option. Change Chemlink.java to:

public class Chemlink {
   public static void main(String[] args) {
      System.out.println("Welcome To ChemLink!");
      System.out.println("It is really good!");
      System.exit(0);
   }
}
      

To see which files are different, use the status option:

cvs status

CVS will display details regarding every file in the project. A specific file may be specified if one only needs to know the status of that file. The status of the file Chemlink.java is as follows:

===================================================================
File: Chemlink.java    	Status: Locally Modified

   Working revision:	   1.5	Tue Aug 13 13:02:12 2002
   Repository revision:	1.5	/usr/local/cvs/chem/Chemlink.java,v
   Sticky Tag:		        (none)
   Sticky Date:		       (none)
   Sticky Options:	     (none)
      

The file is "Locally Modified". In order to determine exactly what this modification is, use the diff option:

cvs diff Chemlink.java

CVS outputs:

Index: Chemlink.java
===================================================================
RCS file: /usr/local/cvs/chemlink/chemlink/Chemlink.java,v
retrieving revision 1.5
diff -r1.5 Chemlink.java
4d3
<       System.out.println("It is fantastic!");
5a5
>       System.exit(0);
      

The revision number is specified and then the diff begins. A line number (4 in 4d3) specifies the location in Chemlink.java that the first difference occurred. The '<' on the next line indicates that the content following is not present in the local version. (5 in 5a5) indicates a difference on line 5, the '>' on the following line indicates that the content following is only present in the local version.

The log option produces a log of cvs project in the working directory, here is the output from executing:

cvs log
RCS file: /usr/local/cvs/chem/ChemElectrovalence.java,v
Working file: ChemElectrovalence.java
head: 1.1
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 1;	selected revisions: 1
description:
Electrovalent bond simulation module
----------------------------
revision 1.1
date: 2002/08/13 12:20:49;  author: blah;  state: Exp;
Added electrovalence simulation
=============================================================================

RCS file: /usr/local/cvs/chem/Chemlink.java,v
Working file: Chemlink.java
head: 1.5
branch:
locks: strict
access list:
symbolic names:
	start: 1.1.1.1
	MySoftwareCompany: 1.1.1
keyword substitution: kv
total revisions: 6;	selected revisions: 6
description:
----------------------------
revision 1.5
date: 2002/08/13 13:03:25;  author: blah;  state: Exp;  lines: +1 -1
Removed an unwanted message
----------------------------
revision 1.4
date: 2002/08/13 12:48:32;  author: blah;  state: Exp;  lines: +1 -0
Added another intro message
----------------------------
revision 1.3
date: 2002/08/13 12:35:34;  author: blah;  state: Exp;  lines: +1 -1
Edited a line in Chemlink.java
----------------------------
revision 1.2
date: 2002/08/13 12:29:17;  author: blah;  state: Exp;  lines: +1 -0
Added a line to Chemlink.java
----------------------------
revision 1.1
date: 2002/08/13 10:38:22;  author: blah;  state: Exp;
branches:  1.1.1;
Initial revision
----------------------------
revision 1.1.1.1
date: 2002/08/13 10:38:22;  author: blah;  state: Exp;  lines: +0 -0
Intial Import - Chemistry Project
=============================================================================

RCS file: /usr/local/cvs/chem/images/oxygen.png,v
Working file: images/oxygen.png
head: 1.1
branch: 1.1.1
locks: strict
access list:
symbolic names:
	start: 1.1.1.1
	MySoftwareCompany: 1.1.1
keyword substitution: kv
total revisions: 2;	selected revisions: 2
description:
----------------------------
revision 1.1
date: 2002/08/13 10:38:22;  author: blah;  state: Exp;
branches:  1.1.1;
Initial revision
----------------------------
revision 1.1.1.1
date: 2002/08/13 10:38:22;  author: blah;  state: Exp;  lines: +0 -0
Intial Import - Chemistry Project
=============================================================================
      

Which shows the log information for all the files in the project, one can also specify a file to retrieve log information for. Notice how my log messages were not very informative, this illustrates how not to write log messages.

A lot of CVS projects are set up so that the repository is on a server somewhere that can be accessed globally via the Internet. This is so that projects can be accessed or contributed to by anyone with an Internet connection. There are two types of remote login.

A remote password server, allows CVS access via a passworded server, the generic formula for accessing repositories like this is:

As an example, consider accessing the Gimp repository to get the latest Gimp sources. Gimp (GNU Image Manipulation Program) is an excellent free image manipulation program for Unix and Windows see http://www.gimp.org/. First of all, one has to know the address of the server, this can usually be found on the homepage of the program concerned.

[Note]Note

Even though one usually uses CVS to version control programs, CVS can version control any collection of files. So while this document refers to programs, the actual content could be any collection of files.

Once the address of the repository is known, the address is placed in the environment variable CVSROOT. This removes the necessity to specify the location of the repository for every command issued to CVS. For the gimp project one would use:

:pserver:anonymous@anoncvs.gimp.org:/cvs/gnome 
    

The :pserver: bit specifies that the CVS repository is stored on a server using the CVS password authentication protocol. The username is anonymous and the server is located at anoncvs.gimp.org, the cvs repository is on the remote machine in the location /cvs/gnome. After setting up CVSROOT, type the following to log in:

cvs login

A password request prompt will be presented:

There is no password for cvs.gimp.org, there will be other servers that are passworded and it is likely that in order to actually contribute to a project one would have to have an account that had the necessary read and write permissions. Enter the correct password. Once the password has been accepted, you will be returned to the prompt you started at. CVS is now ready to accept commands from you that will be executed on the remote server.

Files are grouped into modules, you have to know the name of the module you want to get the files it contains (obviously?). Assuming one wants the module gimp, to get it, issue:

cvs co gimp

This will get out all the files that comprise the gimp module. In order to save bandwidth, one can use the -z option to specify a level of compression to use during the transfer, the command sequence below checks out the gimp module with a compression level of 3:

cvs -z3 co gimp

The compression level specified may be between 0 and 9 but most servers ask not to use a compression level higher than 3 because the losses incurred due to the high CPU load outweigh the gains reaped due to the bandwidth saved.

Once you are done working in the cvs repository, logout with:

cvs logout

If you want to host your own project and let people from all over the world contribute to it, you will need to setup a CVS server on your machine. CVS is not setup as a separate daemon that listens continuously for a connection, it uses Inetd (Internet Daemon) to bind a connection request to the port used for CVS (2401) to the CVS server. The following commands should be executed as root. The file that supplies the information about which ports map to which services is /etc/services, edit this file and add the line:

cvspserver     2401/tcp     # CVS Pserver

It may already be listed, in which case, leave it alone. Edit the file /etc/inetd.conf, add the line:

      cvspserver stream tcp nowait root /usr/local/bin/cvs cvs --allow-root=/usr/local/share/cvs pserver
    

This causes inetd to start up a new cvs server and connect the server to the incoming connection request.

killall -HUP inetd

This restarts inetd. Logon to some other machine and test the access using the cvs login command. By default, users that already have accounts will be able to access the cvs repository with their usual passwords. This is not a very secure way to setup passwords for users since un-encrypted passwords would be being transmitted about, you should instead create the file CVSROOT/passwd in the repository, this contains the list of users that may access the CVS repository, the format is similar to /etc/passwd:

      bob:vF3iFEoi2fOQi:freddy
    

The first field is the username, the second field is the encrypted password, the third field is optional and is a system username mapping. The third field has the effect that the person logging on as the username specified in the first field will have the same access permissions as the system user specified as the third field. For some reason nobody has got round to adding a command to the standard distribution of cvs that can generate and manage the CVS password files. Fortunately there is a tool produced by Raymond Schneider called cvspadm which is designed specifically for this purpose, it can be downloaded from http://hackfoo.net/projs/index.html. Follow the installation instructions to install it.

Besides CVSROOT/passwd there are also the files CVSROOT/readers and CVSROOT/writers which contain lists of users that may read only or read and write to the repository respectively. cvspadm can be used interactively or manually, a screenshot from interactive use is shown below:

This has the effect of adding the following to CVSROOT/passwd:

blah:fxNYnCoaZ629k
    

blah is added to CVSROOT/readers. The same thing can be accomplished by executing the command sequence:

      cvspadm -a -r -u blah -p blah -R c:/cvs
    

You should now be able to accept remote CVS connections. Setting up a CVS server on Windows will not be discussed here, see CVSNT Enhanced CVS Server http://www.cvsnt.org/.

Note that you should be in ~/sw1/ex6 at this time and if you give the command ls it should print something like the following:

243_ex6% ls
Main.java VendingMachine.java
244_ex6%
      

The "cvs import" command, creates a new project in the CVS repository out of ALL the files and directories in the directory that you run the command from. In the following line, replace "username" with your login name.

cvs import -m "Initial Import" Ex6Carton username start

It should respond with something like the following:

N Ex6Carton/VendingMachine.java
N Ex6Carton/Main.java
No conflicts created by this import
[Important]Important

THIS IS WHERE MOST STUDENTS HAVE BEEN GOING WRONG: You cannot use the contents of the current directory for editing. After your import has worked successfully, the best thing to do with the directory you were in when you ran the cvs import command is to delete it (YES: DELETE IT)

cd ..
rm -r ex6

You are now in directory ~/sw1. Now you check out a working copy of the project.

cvs checkout Ex6Carton

It will show you the following output:

cvs checkout: Updating Ex6Carton
U Ex6Carton/Main.java
U Ex6Carton/VendingMachine.java

In checking out the working copy it has made a NEW directory called Ex6Carton (the project name you specified in the cvs import command) Change directory into there and you can start working:

cd Ex6Carton

Now Edit Main.java and VendingMachine.java and add the following lines to the top of the file:

// $Id$
// $Revision$
// $Date$
// $Log$

To put these changes into the CVS repository, use the command

cvs commit

If you have a $Log$ keyword in the file that you commit, cvs will start up your editor with some lines in it that all start with "CVS:" You can ignore those lines but you should insert a brief (1-2 line) explanation of what changes you made in the files since the last time you committed them. In this case, a suitable comment would be:

Added CVS Keywords

Save the file and exit the editor and the commit will complete.

If you do NOT have the $Log$ keyword, then it will not start up the editor.

You only need the cvs update command if multiple different people are working on the same project using the same repository so that you can see the changes that they make. Since you do not share your repository with anyone in this module, you do not need to use cvs update at all (although it will do no harm if you do so, and is a good habit to get into for when you are working on shared projects).

From now on, you mostly just need to edit files and, when you have got your changes working, do a:

cvs commit

However, you may need to add new files: for example Carton.java, when you write it. Use your editor to create a new file Carton.java. Then add it to the repository:

cvs add -m "added new Carton class" Carton.java
cvs commit
[Note]Note

Note that you need to do the cvs commit after adding new files to put them into the repository.

Note that cvs commit, when it finds a changed file that has to be updated into the repository, expands the keywords in the file. Thus the original

// $Id$
// $Revision$
// $Date$
// $Log$

in my Main.java, gets expanded into:

// $Id: Main.java,v 1.2 2002/11/08 21:17:20 aps Exp $
// $Revision: 1.2 $
// $Date: 2002/11/08 21:17:20 $
// $Log: Main.java,v $
// Revision 1.2 2002/11/08 21:17:20 aps
// Added CVS keywords

You NEVER need to edit the contents of these expanded keywords: cvs will update their contents automatically every time you commit a change to those files.

Finally you can see which files are up to date with respect to the repository and which are not by running the command

cvs status

Also you can see the full history of all your changes for each file by running

cvs log

Some students have managed to get themselves into a situation where they do a cvs import and the program keeps running until they run out of disk space (over quota). This problem is usually that you have your repostory directory INSIDE your project directory or you run the import from a parent directory of the repository. Remember, your repository directory should be ~/CVS. Your initial import directory should be ~/sw1/ex6. If you have made your repository directory be ~/sw1/ex6 as well then when you do the import you are trying to add the repository to itself. The recursion that this sets up quickly fills up you disk space. The only thing to do is to (interrupt the cvs import command with Ctrl-C and) delete the repository. Since the repository is quite big at this stage, it is difficult to do it with your usual rm command (because it asks for confirmation for every file) so use the following command instead (careful: this command will delete files without asking for an confirmation: used wrongly you may delete files that you don't want to delete). Let's say your repository is actually ~sw1/ex6/CVS. To delete it, run the command

/bin/rm -rf ~/sw1/CVS

Run 'cvs checkout' first

Some students try to run cvs commit or cvs update and get a message like the following:

cvs commit: in directory .:
cvs [commit aborted]: there is no version here; run 'cvs checkout' first

This means that you are trying to commit in the original import directory (the one you should have deleted after the import) instead of the checked out directory. Read carefully the section above on Importing and getting started.