File Under: Backend, Programming, Software

CVS for Beginners

OK. You and ten of your closest pals have decided to work on the greatest-ever web page/Perl script/whatever. You all want to work on the same file from the same location at the same time. Then when you’re good and ready, you’ll roll out releases of the code.

Does it sound like a logistical impossibility? Well it’s not if you have the right tool — a source control system.

A good source control system is the secret behind any successful web development project. If you look at any large-scale software development project, you’ll see a source control system at work.


  1. Help Me, CVS!
  2. What Can I Do With CVS?
  3. A Sample Session
  4. Tips & Tricks

Help Me, CVS!

When working on Unix systems, the concurrent versions system (CVS) is a great choice. It allows you to manage projects by storing code, configuration files, and even documentation in a central location. It keeps track of version numbers, lets many people edit the same file, and even lets you release code in a (semi) orderly fashion.

In fact, some of the most impressive collaborative software ventures to date, such as Linux, Apache, Mozilla, and Perl, were written with the aid of CVS. For truly distributed code projects like Linux, in which contributors come from all over the internet, it is absolutely essential to use CVS or a similar system.

However, CVS can also be useful for Perl hackers, webmasters, and Webmonkeys.

You can stick anything you like in CVS. Don’t get carried away and put your personal email in there. I suggest you stick to text files, and only those that you care about. Prime CVS candidates for me are Perl scripts, HTML templates, Web server configuration files, and documentation files.

But before you throw just anything in CVS, you’ll probably want to get an idea of what it can do.

What Can I Do With CVS?

If you use CVS to store your files, you can easily manage and release your source code. You can undelete files, reverse changes, and see the differences between your live and development code in a snap. Instead of saving temporary versions of files in weird directories, CVS keeps everything in one place. All this lets you manage your development time more effectively.

CVS is particularly useful when there are many people editing the same file. This problem is the trickiest for collaborative authoring tools to deal with. The makers of CVS decided to please everyone by giving all users access to the same file at any time. CVS then tries to merge changes into the same file automatically.

It works rather well. In the cases where CVS cannot merge changes, for instance when two people simultaneously edit the same line, CVS tells you politely that there is a “conflict” and suggests you resolve this conflict.

CVS is also useful when you want to compare different versions of the same file. Let’s say you need to figure out what changed in a file over the course of a day or a week and you need this information quickly. CVS will give you the information in seconds.

CVS also encourages good software development techniques. CVS almost forces you to commit (or save) code changes regularly and write little comments on what has been updated. Have you finally fixed that weird JavaScript error? Commit your changes to CVS and be sure to write a little note to yourself about it.

CVS allows you to separate development code from live code. And again, tracking version numbers allows you to issue code releases rather than just pushing chunks live.

But CVS is no replacement for an intelligent human being. CVS is not going to write your code for you and it won’t even manage your code unless you use it wisely.

Let’s go over a sample CVS session to get an idea of how you’d use it. There are client applications for CVS that run on both the Mac and Windows PCs. If you’re a Mac OS X user, you can install the Developer’s Tools package that’s included on your installation DVDs (about 1GB total) to get CVS up and running on your local machine. Windows users should check out WinCVS, a GUI app that also has a command line component.

I like typing my commands, so I’m going to use Unix in this session. It might be worth your time to look at our Unix Guide if you don’t know your way around basic Unix commands.

A Sample Session

We need to start working with the CVS repository, which is the place on a Unix server where all files, along with a bunch of metadata, are stored. Within the repository is a series of modules that contain files related to specific projects. We can assume for this demo that there is a module called XML in the repository.

Your sysadmin will need to set up CVS and make the repository available to you. This process isn’t too brutal. The sysadmin should also make sure the repository is backed up regularly and lives in an earthquake-proof/fire-proof/flood-proof/you-name-it-proof room.

Here’s how it works. You check out files from the repository into a working directory where you do your editing. The working directory can be anywhere you like; I tend to use my home directory on the Unix server. Then you use a text editor to make changes. When you’ve polished and tested your code and it’s time to update, you commit files back into the repository.

Let’s go through an example. I’m going to put my XML DTDs into CVS, make some changes, and commit them to the repository. After I telnet into the server, I type the following commands.

 	cvs checkout xml

 	cp webmonkey.dtd  xml/

 	cd xml; cvs add webmonkey.dtd, cvs commit webmonkey.dtd


In the first line I checked out the entire XML module from CVS. Following that, I copied a file named webmonkey.dtd into the XML folder. Then, in the final line, I added the webmonkey.dtd to the XML module with the add webmonkey.dtd command. The line ended as I committed, or saved, the module back to the repository.

You only have to add a file to the repository once. From then on, use cvs commit to update changes to that file to the repository. To save any further changes to webmonkey.dtd that I make in my local directory, I simply type cvs commit webmonkey.dtd.

After I commit the file, CVS gives me this screen:



 	CVS:Enter Log.  Lines beginning with 'CVS:' are removed automatically


 	CVS:Modified Files:

 	CVS:   webmonkey.dtd



 	Checking in webmonkey.dtd;

 	/hot/repository/xml/webmonkey.dtd,v  <--  webmonkey.dtd

 	new revision:1.2; previous revision:1.1


This is your opportunity to add a comment to let the other folks working on the project know what you’re up to. In this case I entered, “Added second ‘author’ tag for dual-authored Webmonkey stories.” Once I committed my changes to the CVS repository, CVS automatically created a new version number for this file.

I can now start to use CVS commands to view version information. Let’s look at version information for the file I just changed. I get this by using the CVS log command. Here, I simply type CVS log webmonkey.dtd, and CVS returns:

 	revision 1.2

 	date:1999/2/1918:49:03;  author:pouneh;  state:Exp;  lines:+50 -0

 	Added second 'author' tag for dual-authored  WebMonkey stories


 	revision 1.1

 	date:1999/2/1913:49:03;  author:pouneh;  state:Exp;

 	added webmonkey.dtd to repository

There are the changes. Pretty cool, eh?

Now, just for the fun of it, let’s say we deleted the webmonkey.dtd file by accidentally typing rm webmonkey.dtd. You wouldn’t need to worry about it. If you type in cvs update webmonkey.dtd, your working directory would be updated with the most recent version from the repository.

Now that you know what CVS is and a bit about how to use it, here are some user tips.

Tips & Tricks

As with any product, there is a right way and a wrong way to use CVS. I suggest you follow these tips carefully in order to reap the benefits of a source control system.

  • Commit your changes to the repository at regular intervals. Think of CVS as a supersave facility. Although you shouldn’t commit files as often as you save them, every time you finish a chunk of code that you are happy with, be sure to commit your changes.
  • Write a short and sweet comment every time you commit a change. If you are ever interested in following the history of your code development, make sure to write a short, intelligible comment every time you commit something. This will really help when you’re doing things like taking down that damn user survey from the frontdoor of your Web site.
  • Update local copies of files regularly. If there will be more than one person working on the same file, update your local copy before you do any work on it. This will pick up any changes from other edits and will minimize the possibility of a conflict.
  • Group related files in modules. You can preserve the directory structure of your code and store it in a module. I save all of my XML DTDs in one CVS module.
  • As you release code, be sure to label the CVS module. Labeling a file sticks a text description onto that version of the file. I use labeling to indicate a software release. A label may be a release number and a short text description.
  • Insert CVS metadata at the top of the file in a comment block. These should include the filename, author, the last person to commit a change, and a log of changes. The metadata will get updated automatically every time a file is updated or checked out. Here’s a sample header from one of my Perl scripts:
#!/usr/local/bin/perl -w

 	# Copyright (C) 1994-99 Wired Digital Inc.  All rights reserved.


 	# File:        $Source:/hot/repository/registration/lib/login/

 	# Revision:  $Revision:1.17 $

 	# Date:        $Date:1999/02/16 22:08:10 $

 	# Author:      $Author:pouneh $

 	# Status:      $State:Exp $


 	# $,v $

 	# Revision 1.17  1999/02/16 22:08:10 pouneh

 	# populated last_update field in DB with user's last login date

  • Finally, make learning CVS commands a regular part of your daily work. Think of them as being as important as the Save command.
  • If you’re interested in more information, take a look at the CVS manual and the CVS FAQ.