These pages are no longer maintained. See my new webpage
Brian P. Gerkey

Photo gallery

USC Robotics Lab CVS How-To

by brian gerkey

What is this?

This document describes how several of us in the lab use the Concurrent Versions System (CVS) to manage and backup our code and LaTeX (among other things). This is not a general CVS How-To. An excellent source of CVS documentation (besides the CVS manual) is here.

Specifically, I'll tell you here how to use the lab servers (tobor/sagan) to store your code and how to access it from your desktop Unix-like machine. Access from Windows should also be possible, but I have no experience with it

What is CVS?

CVS, as the name implies is a version control system. Using it, you can record the history of your source files. Instead of just floating about somewhere in your filesystem, your important files reside in a CVS repository and you check them in and out. It takes a little getting used to, but it's definitely worth it.

Why use CVS?

I give the following reasons to use CVS (with your repository on the lab server):

  • Backup - This is probably the most important one. Unless you personally backup the data on your desktop/laptop, it's not being backed up. This means that if your hard drive breaks (and I guarantee you, it will) or if some malicious scriptkiddie cracks your machine or if someone breaks into the lab and steals it, you're screwed. Even more likely, if you issue a misplaced rm -rf, you've screwed yourself.

    In contrast, the lab servers are backed up. We pay ISD to take nightly backups of those machines. The backups are reportedly stored in a warehouse somewhere in the southwest U.S., probably guarded by aliens. Thus by storing your important files on the lab servers, they will be backed up for you.

  • Version Control - You can always pick back to an earlier version of a file (provided that you check in your changes frequently enough). For example, if you check in your code when it works and subsequently break something, you can go back to the older version. A special (and very convenient) case of version control is the use of tags; see the man page for details.

  • Concurrent Development - As the name implies, CVS was designed to support concurrent development; that is, many programmers working on the same project, even the same files, at the same time. Now, you may not be working on any group projects, but you can benefit from concurrency yourself. For example, when writing your conference paper, you can check it out and modify it on your machine at school, check it in, then check it out again at home and modify it there. Never again do you have ftp numerous versions of your code around with no idea of which is the most current.

How to setup CVS?

Again, I'm assuming you want your repository on tobor/sagan and that you'll access it from a UNIX-like client (probably Linux).
  1. Create the repository
    On tobor/sagan, make a directory for your repository in your home directory. For example:
      $ mkdir $(HOME)/cvsroot
    The name of the directory isn't important.

  2. Pick your access method
    By default, CVS will use rsh to access your repository. If you want to use this method, you'll need to make a file named $(HOME)/.rhosts on tobor/sagan with a line for each machine from which you'll access the repository. For example, if I want to access my repository from, then I'll put the following line in $(HOME)/.rhosts: gerkey
    This means that the user named gerkey on the host will be able to remotely execute shell commands as me on tobor/sagan (without having to give a password).

    Now, you don't have to use rsh; I reccommend that you use ssh instead since it is encrypted. Also, whereas rsh cannot ask for a password (it requires the password-less login described above), ssh can ask you for a password, which is obviously more secure. However, this might be inconvenient for regular access, and so for password-less ssh access, you can create a file $(HOME)/.shosts instead of $(HOME)/.rhosts, but with the same format.

  3. Set environment variables
    On the client (e.g., your Linux desktop machine), set the following environment variables (you might want to set them in your .login or .cshrc or whatever):
    Replace [username] with your username on sagan/tobor and [path] with the full path to your newly created repository. For example, I use:
    If you want to use ssh instead of rsh, also set the following variable:
  4. Initialize the repository
    On the client, do the following:
      $ cvs init
    This will cause CVS to bootstrap your repository with some control files.

How to add files to CVS?

The easiest way to do this is to cd into that directory and do the following:
  $ cvs import [path] [vendor] [release]
Replace [path] with where you want the files (relative to your repository), and, as far as I know, you can set [vendor] and [release] to whatever you want. For example, let's say you've got a directory (on your client side) called /home/gerkey/code/foo that contains some source code you want to add to your repository. You can cd there and do:
  $ cvs import code/foo bpg initial
At this point, an editor will be started (obeying your EDITOR environment variable) and you'll be given a chance to enter a log message describing the files (to avoid starting the editor, you can give the log message on the command line with '-m [msg]'. Check the man page for details). Everything in your local directory has now been added to your repository. You should now check out a fresh copy, but you probably want to create a module first (see below). In any case, you should eventually delete the original directory from which you imported the files and work only in the checked out version; CVS can't do anything for you if you modify files outside of a checked out version.

How to create a module?

CVS can manage individual files and directories, but it can also group them as modules. To create one, you need to check out the special directory CVSROOT from your repository, change it, and check it back in (CVS keeps its own meta-data in CVS; cool, huh?). Something like the following will work:
  $ cd /tmp
  $ cvs co CVSROOT
  $ cd CVSROOT
Now add a line to the file modules of the form:
  foo   code/foo
And check it back in:
  $ cvs commit -m "added the foo module" modules
You can now delete your copy of CVSROOT:
  $ cd /tmp
  $ rm -rf CVSROOT
Now, whenever you want to refer to the file that you added to code/foo, you can use the symbolic module name foo, and not worry about the exact path.

Some useful CVS commands

Check the cvs man page for details, but here are some useful commands to get you started.
  • To checkout a module:
      $ cvs co [module]
    You'll get a local copy in your current working directory.

  • Once you've made changes, to commit them to the repository:
      $ cvs commit [files...]
    You don't have to give the files by name; by default, CVS will recurse down from your current working directory and commit any files that it knows about.

  • To update your local (already checked-out) copy with changes from the repository:
      $ cvs update [files...]
    Just like with commit, CVS will recursively update everything it can if you don't specify files to be updated.

  • To add a directory (to an already checked-out module), first create the directory, then:
      $ cvs add [dirname]
  • To add a file (to an already checked-out module), first create the file, then:
      $ cvs add [filename]
    You'll also have to do cvs commit in order to add the file permanently.

  • To delete a file (from an already checked-out module), first delete your local copy of the file, then:
      $ cvs delete [filename]
    You'll also have to do cvs commit in order to delete the file permanently. Actually, the file won't ever be deleted from the repository, unless you go do it yourself in the repository (not recommended!). The files get moved into directories called Attic, so that they can always be later retrieved.

  • To tag the current repository state of module:
      $ cvs rtag [symbolictag] [module]
    Tagging can be very useful. It allows you to essentially "freeze" forever the state of any code or paper that you're working on, allowing you to retrieve it later. Actually, you can always retrieve any version of any file, but you're unlikely to remember the strange version number that CVS has assigned, so meaningful symbolic tags are much better.

    I use tags like 'submit' when i submit a paper, and 'camera-ready' when i finalize it. I also tag my code with a name like 'iros01' when i've just used it to produce results that go in a paper. That way (or so the idea goes) i can reproduce the data if i want.

What should go in CVS?

Personally, I put the following things in CVS:
  • My program source (including Makefiles)
  • My LaTeX source (including graphics)
  • Small data logs
I don't put in the following things:
  • Object files or executables
  • DVIs or Postscript
  • Big data logs
Basically, I try to only store the source, and count on always being able to compile it when i need to.

A note on binary files: CVS is really only meant to manage ASCII source files. It can handle binary files, but CVS is probably not the best place for them, especially if they are very large. Keep in mind that your repository is taking up your quota space on tobor/sagan.

Last updated $Date: 2004/12/08 16:16:39 $