by Steven J. Owens (unless otherwise attributed)
This is an attempt to give a thumbnail, big-picture overview of CVS for people who really don't know anything about it. Mainly it's an attempt to fill in the gaps and assumptions, the stuff that most CVS-competent people may unconsciously assume people already know.
If this is too lightweight for you, or once you finish reading this, I highly recommend Karl Fogel & Moshe Bar's Open Source Development with CVS.
Note: Since writing this several years ago, a new tool, Subversion (often abbreviated svn) has really picked up steam and started to displace CVS in the hearts and minds and servers of the open source community. Subversion aims to be a "CVS work-alike", replacing CVS, looking and feeling a lot like CVS, while being a ground-up redesign that avoids some key problems in the architecture (two big ones being handling directories better and being able to support atomic comments (i.e. commit a set of changes, undo a set of changes)). Thus, most of the following general comments will apply equally well to Subversion. Karl Fogel has written another book, for Subversion:
To start with, CVS stands for (if I recall correctly) "Concurrent Versioning System" and is a "revision control system", or sometimes called a "source code control system" or "version control system." Any way you slice it, it's a software tool for keeping track of changes to a set of documents.
Since CVS was developed by programmers, for programming, it's geared towards keeping track of plain text files (like source code). It does have some limited ability to include the occasional binary file, but it's really better at tracking changes to text documents.
There's a CVS client for windows, but not a CVS server for windows. For a CVS server you need a unix box.
CVS is free, both free as in liberty (you can get the source) and free as in beer (you don't have to pay anybody if you want to use CVS).
Basically there are four parts to the picture:
Looked at another way, you can think of the client and server software as mediating between your checkout and the repository:
| checkout/working copy | CVS client | CVS server | repository |
You use the client software to "import" a set of project data and source files into CVS, essentially telling the server about them. Importing sends them to the server for the first time. The server sets up a "project", which is a directory hierarchy starting just under the top level of the CVS repository.
Once you've imported the project code, to do any work with the CVS stuff, you have to check out a fresh copy of the project, and work on that. This copy of the project will have a "CVS" directory in each directory of your project. That CVS directory will contain four files, which is what the CVS client uses to keep track of what you're doing in your directory.
You make your edits on the "local checkout" of your project, then you use the CVS client commands, like "cvs update" to make sure you have any code changes that other people have put in, then you build and test your code again to make sure that their changes work with your changes, then "cvs diff" to see what you changed, then finally "cvs commit" to send your changes back to the server to be merged into the repository.
When you commit, the client contacts the server and makes sure that nobody else committed changes to that file between your last update of the file and now. If they have, the client tells you about the problem and aborts the commit.
Seems simple enough, but the part that most people don't emphasize is that you must update, build and test before diffing and committing. The classic goof-up is to miss that something was modified by the update, or to just forget to build and test. The result is that you commit your changes without testing them in combination with the latest changes, and then somebody else updates and gets the broken code and has to deal with your mess.
So really, the traditional sequence (after the initial import and checkout) is:
1) Sit down to work, do "cvs update" to get any new changes.
2) If somebody has changed a file you're also working on, CVS will warn you about the conflict. CVS will insert the changed bits, with special marker lines to show where they conflicted. You go look at the files to examine conflicts and edit them to select the bits you want. If the conflicts are in widely separated bits of the file, CVS may just painlessly merge them.
This process can actually be a little painful if they're complex/ugly changes, so I like to do "cvs -n update" first to see what's going to happen, then sometimes "cvs diff -D now filename" to compare the file in my checkout against the most recent version in the repository.
You can select a specific version of the file to check out - but you have to be careful, because the CVS client keeps track of that (it makes that checkout "sticky", so later updates never get applied to that file until you remove the "sticky" flag).
If you want to check and see what you've changed, you can use "cvs diff filename".
BIG GOTCHA: Most people, in my limited exeprience, assume that
cvs diff filename
...will compare the file against the most recent version in the repository. WRONG WRONG WRONG. It will compare the file against the last version of the file that you checked out/updated from the repository. To diff against the most recent version in the repository without actually updating, do:
cvs diff -D now filename
3) Continuing our story, you update, check any changes that were applied to files you're working on. Then you try to build/run your code and make sure the update didn't break anything :-).
4) Then you work a bit more, until you decide you're done with that bit of owrk.
5) First you update again to make sure any other changes that happened while you were working are applied to your stuff. Then build/run again to make sure your stuff still works. Then and only then you commit.
In a sane and healthy software development team, checking in code that does not compile and run and pass tests properly will get you smacked with a rolled up newspaper.
If everybody remembers to update and build/run/test before committing, then mostly everything works out fine.
Also, remember, CVS is NOT a replacement for teamwork and communication.
Also, DO NOT USE PSERVER for remote CVS use. It's highly unsecure. The normal manner of using a remote CVS client is to use SSH tunneling, and the CVS client normally has support for that built in. You just tell it to use SSH... and of course the user has to have a login account on the CVS server. See the "CVS via SSH" article here at notablog.
If I'm on a windows box, I generally use the cvs command line client that comes with cygwin. There're a couple pointy/clicky CVS clients out there. TurtleCVS is one that I can think of off the top of my head. I dislike them because they obscure too much of what's going on. Though they're nice for getting a big picture, they also seem to lead people into committing too many files at once, in my experience.
Don't forget to have fun.