BOLTS : Click to return to MacEdition homepage

All your versions are belong to you: An introduction to CVS

By Mark Dalrymple (, October 16, 2002

Feedback Farm

Have something to say about this article? Let us know and your post might be the Post of the Month! Please read our Official Rules and Sponsor List.

Prerequisites: Some level of comfort with the command line (see my August BOLTS article). I’m also assuming you’re primarily using plain old text files like HTML files or C source files, so that’s how the examples will be oriented. Also, to actually use CVS or do any of the examples here, you’ll need to install the OS X Developer Tools. They’re either on a separate CD that came with your OS or they’re an installer package in the Applications folder. Anyway, on with the show.

If you’ve been doing much Mac programming (or programming in the Unix world), you’ve probably heard the terms “revision control” and “CVS” before. That’s what I’m here to tell you about.

Further Resources

The source. The CVS home page and the official CVS documentation (also called the “Cederqvist”, named after the author). It’s actually pretty readable for technical docs. You can skip over chapter 2 (which dissects the repository) when you’re learning this stuff.

Open Source Development in CVS by Karl Fogel. This is my favorite CVS reference. It’s easy to read and approachable, plus it covers just about all of CVS, including configuring network servers. The even numbered chapters (on CVS) are published free on the Web at The other chapters (about open-source projects) are in the printed book.

The CoocaDev Wiki has a CVS intro and CvsWrappers tutorial at:

Cocoa Dev Central has an intro on using ProjectBuilder’s CVS features at:

Apple has a great overview at:

Badgertronics offers a brief command-line reference:

Version Control (also known as “Source Code Control” and “Revision Control”) is keeping a history of the changes you make to a set of files, whether they be Objective-C or Java source files for a program, or HTML and CSS files for a Web site. After you make a change to file you tell the revision control system to remember that change. The system remembers all of your changes and when you made them so you can, for instance, figure out what the file looked like at a particular instant in time or figure out the changes in the file between two different dates.

Multiple people can interact with the same version control repository, which is the place where the system stores the past versions of the file, and these folks can all contribute to the same body of work. The version control system keeps track of who changed files when, and what those changes were - in essence, an electronic paper trail. Handy for figuring out who introduced a problem so you can go and flog them with noodles. Aside from the blame game, version control systems help multiple folks contribute to the same project without stumbling on each other and losing people’s work.

CVS, the Concurrent Versions System (some folks call it the Concurrent Versioning System), is an established open-source version control system that is really popular out in the open-source community and also happens to come installed with developer tools.

Version control systems usually work with one of two principles. The first is “lock, edit, unlock.” If you want to change a file you first lock it, thereby preventing other people from editing the file. Make your changes (and test them, hopefully), and then tell the system to accept your changes and unlock the file. Then the next person can lock the file and make his changes.

The other model, which is what CVS uses, is an “edit, merge” model. The idea is that every person is toiling on her own personal copy of the program (or Web site, or whatever). They’re free to edit any file there. Once they’re done editing, they ask the version control system to merge the changes into the original. If there are no conflicts, the changes are added. If there are conflicts (like I change a word to “Tomato” and you change it to “Tomahto”), the person checking in the new version is asked to resolve the conflicts. This model scales up much better with larger, more distributed teams. Plus you don’t have the problem of someone locking a file and then flying to Aruba for a couple of weeks.

The big questions

The first question to ask when considering using a version control system is “should I use it?” In almost all cases, the answer is a resounding Yes. The benefits of version control, such as being able to reconstruct your code base as it existed at any point in time and being able to back out mistakes are huge compared with the small amount of overhead it adds to the development process. Even if you’re a single developer and no one else will be touching your stuff, a version control system is a great tool. You’re free to experiment knowing that prior versions are available if the experiment turns out to be horribly wrong.

The second question to ask is “should I use CVS?” I would say, yes, if you’re using it for an existing project or for a project where you have a good idea how it will be structured. That is, what files will be living in what subdirectories. CVS can be inconvenient if you need to move files and directories around. CVS can also be inconvenient if you’re doing a lot of branching (multiple independent trails of revisions of the same file) or are dealing with a lot of binary files. In those case you may be better off with Subversion or BitKeeper.

OK, enough theory; Let’s play

I’ll be showing everything from the command line, but there are some graphical CVS front-ends if that’s more your style. Check out VersionTracker for more details. Also, everything I’m doing is going to be relative to my home directory. If you see the tilde (~) character in commands, that’s a shell shorthand for “home.”

First off, we’ll need to make a repository, the place where CVS stores copies of your files as well as the information necessary to reconstruct the version history. You only need one repository for all of your different projects. Here’s the command for making a repository:

% cvs -d ~/cvsroot init

CVS commands can be composed of up to 4 parts:

The global-options are generic options that are applicable to all commands. The command is a word that tells CVS what you want to do, whether it be adding files, seeing an annotation, checking the status of a file, or seeing what’s different between versions of a file.

In the init case above, -d tells CVS what directory contains the repository. The init command creates a new repository in that location.

CVS has built-in help. To see all of global options, you can enter:

% cvs --help-options

To see the different commands that are available, enter:

% cvs --help-commands

Some of the eagle-eyes out there may be saying “Wait! Last time you told us command-line arguments use a single dash, and are one letter.” True, most Unix arguments are like that. The folks at the GNU project introduced “long arguments” using two dashes and more readable names. Frequently, programs will accept a traditional cryptic argument and a long argument to do the same thing.

Next Page: You’ve got your repository, so put something in it

Mark Dalrymple ( has been wrangling Mac and Unix systems for entirely too many years. If you need a custom Mac OS X application developed, boing on over to Borkware and we’ll talk.

E-mail this story to a friend