Some quick CVS notes

Author: John M. Gabriele
Date: May 2007
Back to:homepage

Contents

Overview

These are my notes on working with CVS. This doc assumes you already know what CVS is and why you'd want to use it. To read the docs that come with CVS (the "Cederqvist"), use info cvs. You can also find versions online.

To get very brief command line help on using cvs, try:

cvs --help
cvs --help-commands
cvs --help-synonyms
cvs --help diff
cvs --help update
cvs --help <some_command>

The cvs client

When running the cvs command, probably the most commonly-dealt-with environment variable it pays attention to is $CVSROOT which points cvs to the repository it's going to be dealing with. You can always override CVSROOT by using the -d option with cvs.

Most typically, you:

Creating a local repository

  1. You've already got a local directory that you've been working in. It contains source code, maybe graphics, maybe a makefile, various config files, etc. Let's say that directory is /home/john/dev/cool_proj.

  2. You've chosen a place (and created a directory) for your repository. It's /home/john/repos and it may soon contain a number of projects besides our cool_proj.

  3. From any directory, create the repository:

    wherever$ export CVSROOT=/home/john/repos
    wherever$ cvs init
    

    Note: that previous step doesn't actually import any files into the repository, it simply initializes a new repository. Also, don't ever edit any of the files in your repository. For editing, you'll be using copies of all your versioned files, a sandbox (a.k.a. "working directory").

    cvs init creates a bunch of administrative files in (for this example) /home/john/repos/$CVSROOT.

Importing a project into a repository

Now put your cool_proj project into the repository you just created:

cd /home/john/cool_proj
cvs import cool_proj some_vendor_tag some_release_tag

Notice that, although the name of the CVS module here cool_proj is the same as the name of the directory it's in, it doesn't have to be (though it usually is).

You have to put something in for "vendor tag" (possibly just your username) and "release tag" (possibly something like "start").

To complete the import, you'll be taken to an editor (usually nano or vi) to enter a comment for the initial check-in. Most folks just write "initial check-in" here. Type something, then save and exit.

If you had any binary files in your original source code directory, they will have been successfully imported into your repository, however, you'll need to manually mark them as binary later on (as soon as you create a sandbox) with cvs admin -kb a_binary_file

Now that the files in /home/john/cool_proj are safely checked-in to your repository, mv cool_proj cool_proj_ORIG so you'll have a backup of your original files. If you want to look in on your versioned files, cd to your repository and take a peek. You'll notice the versioned copies will have ",v" at the end of their names.

Creating and working in a sandbox

Ok, you've got (or have access to) a source code repository and have set up your $CVSROOT environment variable. Here's how you get started working with some code.

  1. cd to a directory where you want your working copy of the source code (your sandbox) to land. Check-out a working copy:

    cd ~/dev
    cvs checkout cool_proj
    

    Note that you use the name of the module, like it is in the repository, and like it was typed in with the cvs import command.

  2. Modify your files in ~/dev/cool_proj.

  3. Commit your changes to the repository with either cvs commit from the ~/dev/cool_proj directory, or else commit files from some subdirectory of cool_proj, or else commit individual files, ex.: cvs commit my_file.pl

  4. If this was a repository being used by other users (perhaps other users on this computer, or else if we were using a remote repository that other users had access to), we'd first do a cvs update from ~/dev/cool_proj to get the very latest files in our sandbox -- in case others had done commits while we were away. To get any new directories that might've been created, use cvs update -d.

  5. Read the docs on these other common commands you'll likely be regularly using:

    • cvs add file_name (use the -kb option for binary files)
    • cvs remove file_name
    • cvs status [file_name]
    • cvs log [file_name]
    • cvs diff [-r some_revision] file_name
    • cvs tag some_name_for_this_release

Tagging your tree

To do.

Showing all changes since some given tag

To do.

Checking out to make a release

If you'd like to do a checkout, but not get any CVS administrative files (say, you just want the source so you can tar it up and send it to some friends):

cvs export -r tag_name -d my_proj-1.3 my_proj

Yes, -r usually means "revision number", but here you pass it a tag name.

Removing a sandbox

To tell the repository that a whole module in your sandbox is no longer in use:

cd ~/dev
cvs release -d cool_proj

This updates the repository's history file accordingly and then recursively deletes that project's sandbox and anything in it. If you omit the -d, your sandbox will be left intact.

Removing a module from your repository

The faq indicates that, if after release'ing your module you wish to remove it completely from the repository as well, you may then cd into the repository and rm -fr the project directory.

A quick recap on directory locations

Merging

When you do an update, cvs automatically attempts to merge any changes in the repository into your working files. It usually does this just fine.

Now, it may be that you've made changes to your working copies but not committed those changes. Again, still fine. But it may also happen that someone else has committed their own changes sometime after your last update ... and changed the same lines in the same files as you. If this happens, cvs can't handle the merge on its own, and it will tell you so. For a file named foo.c, you'd see:

rcsmerge: warning: conflicts during merge
cvs server: conflicts found in foo.c
C foo.c

In this case, your working copy of foo.c will now have some new marks in it (added by cvs) that look like "<<<<< foo.c" and ">>>>> 1.x". Your job is to go and edit out those marks, and to manually merge your changes with what's now there.

Your original file (as it was before the attempted cvs upd) will be stored in a new file named .#<name>.<version>.

When done editing, try to cvs ci the file.

Using a remote repository

Everything is the same with using a local repository, except that you:

  1. first need to know how the CVS server is doing authenticating, and
  2. need to set up some environment variables so you're cvs client knows who to connect to.

In general, you'll be running the cvs command like so:

cvs -d [:METHOD:][[USER][:PASSWORD]@]HOSTNAME[:[PORT]]/path/to/repository command [options]

where the -d option is telling cvs where to find the repository (above we'd set the CVSROOT environment variable for this -- you may use either method).

What's really going on, on the remote machine?

If a CVS repository is set up so that others can connect from a remote host using the pserver method, then you must have either a daemon CVS pserver process running on that server machine, or else have something like inetd kick it on when users connect looking for a repository.

If the user connects to the remote repo using the ssh method, there's no server process involved -- they just need a shell account on the remote system. cvs does the work of talking to the remote repository and sending the files back to your machine XXX (double-check this).

Which kind of authentication?

There's two different ways your cvs client can authenticate with the remote repository: "pserver" ("password-authenticated server") or else ssh. pserver is usually only used for anonymous CVS. If the server is using pserver, you first need to log in:

cvs -d :pserver:anonymous@cvs.foobar.com:/opt/cvs login

and then you can run the usual co command to get the source.

Environment variables

When using the ssh authentication method:

export CVS_RSH=ssh
export CVSROOT=:ext:john@somewhere.org:/opt/cvs

If using pserver, you might just skip setting env vars and just use the commands like shown in the section above.

Backing up and restoring a repository

As described in the faq, you can just tar up a repository and move it to a new location. Then just make sure your cvs client knows how to reach it.

Learning more...

Some links