Skip to main content
Department of Information Technology

Using CVS

Creating the Group Repository

You will have one repository against which all members of your group will check in and check out files. This is created in the home directory of a group member.

  • Appoint one member of your group to be the holder of the cvs repository. This is the central location where all files will be stored permanently. The customary name is ~USER/cvsroot. So we assume that in the following, with a user named adam.
  • Create the directory cvsroot:

cd ~adam
mkdir cvsroot

  • Initialize the directory as a cvs repository:

cvs -d ~adam/cvsroot init

Now you have an empty cvs root directory!

Next, we create the directory actually containing our source files, and a dummy file inside it. This is done in the place where you will be working with your files. For this example, we assume this to be ~adam/src/compsys.

  • Create the directory:

cd ~adam/src
mkdir compsys

  • Enter the directory and create at least one file. Cvs cannot start the project unless there is at least one file existing. This is a known and accepted limitation in cvs.

cd compsys
echo "dummy" > README

  • Now it is time to import the files into cvs, which will create the actual project repository. The import command requires that you give a message (-m), the name of the repository (in this case, compsys; this name will be used when checking out the project), and two dummy values for creator and label. We use -d to tell cvs where the cvsroot is to be found. Note that it is critically important to do this inside the directory where the files are!

cvs -d ~adam/cvsroot import -m "beginning of our OS" compsys we start

  • Now Adam has a working CVS repository. However, there is one last step that is necessary to complete his setup. The directory whose contents he imported was not set under cvs control, which is necessary to keep working in good order. So now adam should do the following: convert his directory into a backup, and checkout a proper CVS tree. This is done with the following commands (still in ~adam/src/compsys):

cd ..
mv compsys compsys_bak
cvs -d ~adam/cvsroot checkout compsys

  • Finally, adam has a compsys directory under cvs control. He can check that it is indeed working by doing the following:

ls compsys

The directory contain all the files found in the original directory, now called compsys_bak, and a directory called CVS, which contains cvs data.

Note that you can use the same repository for multiple projects; each "import" command will create a new structure in the cvs repository. It might be handy to use cvs in future courses too!

Setting up a Working Environment

Another member of the team, call her Beata, will now want to start working with the files. To do this, she needs to do the following:

  • Move to the place is her file structure where she wants to put the project directory. We assume that Beata has a different way of naming compared to Adam, and wants to put it under ~beata/courses.

cd ~beata/courses

  • Then she needs to checkout the files. This requires her to give the name of the repository and the name of the project to cvs.

cvs -d ~adam/cvsroot checkout compsys

  • This should create a directory called compsys, which contains the file "README" that was created above, and a directory CVS that contains private cvs data cached locally. Just like Adam had in his initial directory as detailed above.

Working with CVS

To work with cvs, the recommended method is the following:

  • Whenever you start working for a day, do a update. This will give you any changes that other people have checked in. Do this when located in the project directory, and then giving the cvs command. For Beata, this would mean:

cd ~beata/courses/compsys
cvs update -d -P

Note that we added "-d -P" to the update command. This means that we ask cvs to add any subdirectories that happen to be missing in our working directory (-d), and to remove, or prune, any files that have been deleted (-P). These are the "standard options" used when updating with cvs. Notice that there are two places to give options to cvs on the command line: after the "cvs" command but before the actual cvs action ("update", "commit", "init", etc.). Such options are "global" and specify the root directory etc. The options coming after the cvs action are specific to the particular action.
  • If you have made changes to files, you should first do an update, and then commit any changed files. Assume that we have changed the file called foo.txt locally. We then give the command

cvs update -d -P

This will result in the following output from cvs:

M foo.txt

The file "foo.txt" is marked as "M" for Modified. The change is still only local, so we need to commit it to the repository. Which is done using the command:

cvs commit -m "changed something" foo.txt

The -m option to the commit action gives the message stored in log for the file. It is a good idea to always give a brief account for the changes done when committing changes.
  • If you add a file, you will need to explicitly add it to the repository. We assume that you have added a file called bar.txt. The command sequence is the following:

cvs update -d -P	

The output this time shows us an unknown file, with a question mark:

? bar.txt

Add it using the add action:

cvs add bar.txt

This only schedules bar.txt for addition; to complete the addition, you need commit also:

cvs commit -m "new file added" bar.txt

For adding subdirectories, the commit step is not needed. cvs is not very consistent in this manner.

Conflicts

CVS is a concurrent versioning system, meaning that several users are allowed to change the same file concurrently. As changes to a file are being checked in, cvs will try to merge the changes into a single version of the file incorporating all changes. This usually works automagically and well, but sometimes conflicts occur. This means that CVS was not able to resolve all changes, and that you have to fix things manually. A conflict is marked by the much-dreaded "C" in the status from cvs update:

C foo.txt

When this happens, open the file, and look through it for the cvs conflict markers, which is a line of <<<. Edit the file until it is correct, and then commit it as usual.

Tagging your Files

To easily keep track of changes among project members, you should keep a change log in each file. This is done by inserting the following comments first (or last, depending on preference) in all your source files (the example is for C, enclosing the tagging within a C comment):

/*
  Current version info:
  $Id: $

  Change log from cvs:
  $Log: $
*/

When checking in files, the commands within dollar signs will be replaced with data from the checkin. In particular, the -m messages will be put in the log. Putting in understandable and informative check-in messages is mandatory in this project assignment. As is having a history log in each source file.

CVS from Emacs

A more convenient way of using CVS is the pcl-cvs mode in Emacs. It is usually accessed by issuing "M-x cvs-update" to Emacs. The cvs mode should be self-explanatory. Note that you cannot create a repository from within Emacs, only work with checkouts and updates.

Updated  2004-08-29 14:41:54 by Jakob Engblom.