CVS

Also, have a look at the page on Subversion. It is a little nicer to use than cvs, and is a little more powerful too.

What is CVS and Why Should I Use it?

CVS (Concurrent Versions System), is a version control system. Normally when a file is saved only the state of the file is permanently recorded. CVS allows you to not only save the state of the file but also a history of all the changes made to that file.

This history of changes provides some important benefits when working with your files. Imagine that you are writing a huge program that is almost working perfectly. You add a few changes, they seem to work fine, and you keep working. A lot of changes later, you realize that the earlier changes did not work quite the way you intended. Now you need to fix them. Unless you have an exceptional memory and can recall all the minute additions you have made, fixing your changes is going to be a good deal of guess work. CVS takes out the guess work. It lets you query your files to discover what those changes were and when they were made.

Another reason to use CVS is for group projects. CVS allows multiple people to edit files at the same time, and it intelligently merges the changes. This feature also helps you when you want to code on different machines without worrying about transferring the source code between machines manually. If used correctly, CVS also guarantees that you won't be using old versions of files.

Some Terminology

Though at first some of these terms may seem illogical, as we walk through some examples and you start using CVS they will make more sense. :Repository: A CVS repository is the location where CVS stores all of the files that it tracks.

Warning

Files in this directory should almost NEVER be accessed directly by the user.

Module:A module is a directory inside the repository.
Revision:Every file in the repository has a revision associated with it. A revision is a number of form x.x that represents the number of times changes to a specific file have been made.
Release:In CVS circles, the current state of the code is referred to as the release. This is synonymous with what we usually think of as a version.
Tag:A tag is a symbolic revision number. In other words, you can give a group of files a certain tag and then whenever you want that set of files you use the tag to select them. This will make more sense when we talk about commands.
HEAD:HEAD is a tag for the most recent revision of every file in a module.
Branch:A branch is a tag that allows you to make changes to a set of files without changing them on HEAD.

Setup

Creating a Repository

All that you will need is a directory under your home directory. I recommend using something like cvsroot or cvs. Here are the steps to create it and enable CVS to use it:

cd ~
mkdir cvsroot
chmod 700 cvsroot
cvs -d $HOME/cvsroot init

After creating this directory you must vow never to touch it again. The CVS tools will deal with all the files there properly.

Environment Variables

You will need to set CVSROOT to your repository path. If you are using bash you would add this line to your .bashrc:

export CVSROOT=$HOME/cvsroot

If you are not comfortable using vi, you will also want to set the EDITOR variable to your preferred editor.

Common Commands

Creating a Module

To begin working with CVS we need a module. This can best be shown with an example. Let's say that I have the code for this document in ~/public_html/cvsdoc. To create a module for it, I would do the following:

cd ~/public_html/cvsdoc
cvs import cvsdoc byronc start

This creates a module called cvsdoc. The byronc and start are known as vendor and release tags respectively. When you are just using CVS for personal projects these tags are not very important, using your username and start should be sufficient.

After you have followed these steps all your files are now stored in cvs and you can delete the directory you ran the import from. In my case this would mean deleting ~/public_html/cvsdoc.

A Typical CVS Session

The best way to work with source managed by CVS is to create a working directory. This directory is often called a sandbox. I usually use ~/develop/cvs. The next step is to get a copy of the code in the module that you want to edit. If I wanted to work on the cvsdoc module that I created earlier I would use these commands:

cd ~/develop/cvs
cvs checkout cvsdoc

This will create the ~/develop/cvs/cvsdoc directory and create the most recent version of each file in that module. Now I would make the changes to the code that I wanted to.

After making changes, the files in ~/develop/cvs/cvsdoc exist only in my working directory, and not in the module. To add those changes to the version in CVS, the files have to be committed. The easiest way to do this would be:

cd ~/develop/cvs/cvsdoc
cvs commit

An editor will start and you should enter a comment about the changes that have been made.

When we are done editing the code we have to release the module so that CVS doesn't think it is still checked out. To do this is as simple as going to the parent directory and running the cvs release command like this:

cd ~/develop/cvs
cvs release -d cvsdoc

This will tell us what files have been altered and ask if we want to release and delete the directory. Deleting the directory is a good thing in this situation so that we don't end up working on old versions of code.

Working with Tags

After working on this code for some time it is likely we are going to have a version that we want to release or pass off. A nice feature of CVS is that we could apply a tag to the current revision of all the files and then if we ever wanted to look at that set of files we could use the tag to find it. The easiest way to create a tagged version is to check the files out and tag them. The following is how to do this using the example I've developed throughout this document:

cd ~/develop/cvs
cvs checkout cvsdoc
cd cvsdoc
cvs tag rel-1-0

This will apply the rel-1-0 to the current revision of every file in the module.

If I wanted to work with those files again, I would check them out with these commands:

cd ~/develop/cvs
cvs checkout -r rel-1-0 cvsdoc

Remote Access

One of my favorite uses for CVS is to maintain my source while I work on it from two different machines. It makes it easy to be sure that I am always getting the current code, and I don't have to worry about making a tarball, copying it, untarring it and making sure that I have the right files.

Warning

If you are just using two of the Linux boxes in the CS labs you don't need to do this--you already access the same home directory from every machine in the Open Labs. This setup is for adding a computer outside of the CS Department.

Using CVS remotely is incredibly easy. You will need to pick one of the [http://docs.cs.byu.edu/docs/cvs/5.php Linux lab names] or schizo to use in order to connect to your CVS server. For this example I am going to use monsters. Just add these lines to your .bashrc on the computer you want to work from:

export CVSROOT=byronc@monsters.cs.byu.edu:/users/admin/byronc/cvsroot
export CVS_RSH=ssh

You will most definitely want to use your username and your full home directory instead of mine. You can find what it is by running these commands on one of the lab machines:

cd ~/cvsroot
pwd

After doing that you will be able to use the same commands to checkout your code and commit it, although you will be asked for a password on those operations.

Learning More

This is a very brief introduction to CVS. There is so much more to learn. One powerful feature that I did not explain is branches. I highly recommend reading the cvs manual at http://www.cvshome.org/docs/manual

There are also two useful documents on The Linux Documentation Project about CVS. The first is the howto: http://www.tldp.org/HOWTO/CVS-RCS-HOWTO.html, an introduction to CVS and RCS. The second is the CVS Best Practices document: http://www.tldp.org/REF/CVS-BestPractices/html/index.html, an extremely useful set of tips about how to use CVS correctly, so you don't shoot yourself in the foot.