Aaron Swartz
How to Do Stuff

How to Do Version Control with CVS

Pick a directory to put the CVS repository (where all the file history is stored). For concreteness, we’ll say /Users/joe/Documents/cvsroot/

$ cvs -d /Users/joe/Documents/cvsroot init

This initializes the repository. Now you’re ready to put stuff in it.

Enter the directory you want to be CVS controlled:

$ cd ~/Projects/MyProject

Now you can import the current directory (the one you’re in) into CVS:

$ cvs -d /Users/joe/Documents/cvsroot import -m "initial import" myproject me initial

Each CVS version of a file has a message, or comment attached to it. Most people use these to note what changes were made in that checkin. Here we use -m "initial import" to say that the message used for this the first version of all these files should be "initial import".

Each CVS repository holds several different modules (projects) which can be checked out individually. In this command line, ‘myproject’ is what you want the module containing the current directory to be named. (‘me’ and ‘initial’ are vendor and release tags, respectively, and nobody I know ever uses them so it doesn’t matter what they’re named.)

OK, so now you’ve got a CVS repository set up. The next thing to do is to "check out" an instance of it:

$ mkdir ~/VersionControlledProjects
$ cd ~/VersionControlledProjects
$ cvs -d /Users/joe/Documents/cvsroot checkout myproject
(`myproject' is the module name we assigned above.)

Now CVS will make a lot of noise and create a directory named ‘myproject’ which contains all the files the directory you checked in did (hopefully). This directory is “controlled” by CVS.

Now you can edit these files using whatever program you want. When you’ve finished making a change and want it to be archived, you can checkin the current state of the code with cvs:

$ cd ~/VersionControlledProjects/myproject
$ cvs checkin -m "added the fobnitz component"
(assuming the change you made was adding the frobnitz component)

CVS will check the files you have against the version archived in the directory, and take all the differences and archive those as a new version. CVS will say something like:

new revision: 1.2; previous revision: 1.1

1.2 is the version number of this new modified file.

If you create a new file, CVS won’t automatically check it in. You have to do:

$ cvs add newfile

and then it will be checked in the next time you run cvs checkin (cvs commit, cvs ci, and cvs checkin are all the same thing).

If you or someone else checks in a change from another directory, it won’t automatically propagate to your directory. To get CVS to look for new updates and apply them to your files, run:

$ cvs update -Pd

Variant: Running CVS over a network

If you want to run CVS over a network, everything is the same as the instructions above except for a few changes. First, pick the computer (the server) you want to have the CVS repository. For concreteness, say this is cvsmac. Run an SSH server on cvsmac. (On Mac OS X, you can do this by going to System Preferences/Sharing/Services and checking the Remote Login box.) You also need an account on cvsmac. For concreteness, say it’s named joe.

Now in every session before you run CVS, run:

$ export CVS_RSH=ssh

(To automate this, add it to your .profile.)

Now, instead of running:

$ cvs -d /Users/joe/Documents/cvsroot  (some command)

in the commands above, run:

$ cvs -d:ext:joe@cvsmac: /Users/joe/Documents/cvsroot/  (some command)

CVS will ask you for your password and connect over the network to execute the command on the other machine. (But checkouts will create a directory on the machine you’re connecting from.)

Recovering files from CVS

To recover version 1.7 of criticalfile, just run:

$ cvs update -r 1.7 criticalfile

(You can also do -D date to specify a date instead of a version.)

Running:

$ cvs diff criticalfile

will show the changes you made since you last checkin critical file.

$ rm criticalfile
$ cvs update criticalfile

will delete criticalfile and replace it with the last checked in version. (You’ll lose any changes you’ve made!)