CVS is a revision-control system; i.e., it keeps track of changes to a body of code (or other collection of documents). It's worth mentioning at the outset that there are several alternatives to CVS available at Khoury. One is Subversion (svn), and Subversion is available on the command line from our Linux machines. Another is Git, which we support on the Linux command line. Yet another is Mercurial. We also have a github enterprise instance running at https://github.ccs.neu.edu.
(There's also a much older version-control system that operates only on the level of individual files, not whole projects, called RCS. We do not recommend using it for new work.)
Introduction: What are CVS and SSH?
The Concurrent Versions System, or CVS is a tool that keeps an archive (called a repository) of the source code associated with a project, and lets multiple people, perhaps at multiple sites, check out copies of the project, edit them, and automatically merge their changes back into the original repository. It's typically used to allow a group of people (perhaps geographically dispersed), to collaborate on software development. It can also be used to synchronize data between multiple machines (e.g. to keep the copies of certain files on computers at different sites in synch). You can find CVS news, downloads, and documentation at Ximbiot - CVS Wiki.
In its simplest usage, CVS lets you access a repository stored in the filesystem of the computer you're sitting and typing at. But CVS also lets you access repositories stored on remote computers, in a few ways. The one we support at Khoury involves running CVS over an SSH connection, as described below. This requires that you have a login account on the machine the repository is on, and that that machine have the CVS software available. This means that you can sit at a Khoury machine and access a repository stored on a non-Khoury machine (assuming it has SSH and CVS installed on it), and you can also sit at a non-Khoury machine (again, with SSH and CVS) and access a CVS repository on a Khoury machine.
SSH, or Secure SHell, is a more secure alternative to telnet or rsh. It lets you log in or run individual commands on a remote machine. It has one huge advantage over rsh and telnet: all the information transferred between the two machines, including passwords and/or identity keys, is encrypted. That makes it harder for a person connected to the network somewhere between where you are and where the computer you're logging into is to steal your password. (They would probably need to break into one of the endpoint computers, rather than just watching the traffic going between them, which is easy to do.)
SSH is typically used as a replacement to "rlogin"; if you connect to login.khoury.northeastern.edu with your Khoury account name (username), typically you will be prompted for your password on that machine, and then get a login session. (There are ways to configure SSH so that instead of prompting for a password, it asks you for a passphrase that accesses a key that proves that you're the person authorized to make that connection. If you do that, there are also ways to avoid having to type the passphrase for each connection, so you can type it once at the start of your session, and then you won't be prompted for a password or a passphrase when you make SSH connections. That's a bit tricky, though, and is beyond the scope of this article.)
However, command-line implementations of SSH also allow you to run a single command on a remote machine. For instance, if you type
ssh -l jay login.khoury.northeastern.edu whoami
you'll be prompted for user jay's password on the machine ‘login.khoury.northeastern.edu’, and if you type it correctly, the ‘whoami’ command will be run on that machine and you'll see its output on your machine.
How CVS and SSH work together
CVS uses this latter facility of SSH. When you use the cvs command on a local machine to access a repository on a remote machine, the local cvs command connects via SSH to the remote machine, and runs another cvs command there, with arguments saying what you want to do with the remote repository. The two cvs commands coordinate transferring any needed data over the SSH connection to perform the function you've asked for. (This can also be done, much less securely, over rsh. We don't allow rsh from remote machines to Khoury, but if you need to access a CVS repository stored on a remote machine that supports rsh but not ssh, you may need to risk doing this. Fortunately, such machines are increasingly rare.)
Telling CVS to use SSH
In order to use SSH (or more specifically, the ‘ssh’ command) for remote CVS access, you need to set the Unix environment variable CVS_RSH to ssh. You can conveniently do this in the appropriate dotfile for your login shell (such as .tcsh.cshrc or .profile).
You can generally do this by adding a line that says
CVS_RSH=ssh; export CVS_RSH
to your .bashrc, .kshrc, .zshrc, or .profile file, or by adding a line that says
setenv CVS_RSH ssh
to your .cshrc or .tcshrc file, depending on what shell you use. Recently created accounts at Khoury use the bash shell and therefore use the first form in the .bashrc file; older accounts (before July 2009) defaulted to tcsh and therefore would require the second form in the .tcshrc file.
Specifying a remote repository
To specify a local repository, you simply provide the full pathname (in the "CVSROOT" environment variable or as an argument to the "-d" option). For instance, the command
cvs -d /proj/myproj/cvsrepository checkout foo
will check out the project called foo from the CVS repository based at /proj/myproj/cvsrepository in the local filesystem.
You specify a remote repository in the form ‘:ext:user@hostname:pathname’. The ‘:ext:’ says you're using an external program (in this case ssh) to access the repository. hostname is the name of the machine to connect to (the machine the repository is on), user is your login name on that machine, and pathname is the full pathname to the repository on that machine. For instance, to access the above repository from a remote site, a user with username jay would issue the command
cvs -d :ext:firstname.lastname@example.org:/proj/myproj/cvsrepository checkout foo
This will access the repository by SSH'ing as user jay to the machine login.khoury.northeastern.edu. Depending how user jay have SSH configured, it will probably ask for password on that machine.
For a repository stored on our central file server at Khoury (e.g. in your group's /proj space), hostname can be any machine you are allowed to log in to. For instance, if you have a workstation on your desk, you might want to use that.
Setting up a repository at Khoury
Most of this document describes connecting to a repository that already exists. However, when you set up an initial repository, there are some things you should do to make sure people within your group have access to the CVS repository and other people don't. (This discussion applies identically to local-filesystem access to the repository and ":ext:" access via SSH, since both rely on Unix file permissions and your developers' Unix accounts' privileges.)
When you create a new repository with "cvs init", CVS sets permissions such that all the files and directories that need to be group-readable are. However, the new repository Iand the "CVSROOT" directory within it) will be created with their group-ownership set to your default group (typically faculty or grads). That's almost certainly not what you want. You'll probably have a Unix group that all the people working on your project (and nobody else) are members of that should have write-access to the repository. You'll need to recursively change group ownership to that group (e.g. with a command like
chgrp -R mygroup /proj/myproj/cvsrepository
However, new directories created within the repository will still have the default group ownership of the user who creates them. To change that, you can give all the directories (to start with, the repository directory itself and the "CVSROOT" directory within it) the setgid bit with commands like
chmod g+s /proj/myproj/cvsrepository
chmod g+s /proj/myproj/cvsrepository/CVSROOT
On Linux (and Unix) systems, the setgid bit on a directory means that new files and directories created there will inherit the directory's group (and new directories will also inherit the setgid bit, so this is recursive). That should let members of your group easily import projects and create new directories in them without much hassle.
CVS creates a couple of files ("CVSROOT/history" and "CVSROOT/val-tags" within a new repository with world-write permissions. We are not certain, but we suspect this may be necessary in order for anonymous "pserver" access (even read-only access) to the repository, but it also means that anyone on the system can mess up those files. We don't believe world write access to these files can actually cause source code to be lost, but it might cause the "cvs history" command to report erroneous information, and/or cause temporary problems using CVS that would require hand intervention to fix. If you don't want anybody but your group to have access to your repository (even read-only access), you can safely remove the world-writable bit from all those files with a command like
chmod -R o-w /proj/myproj/cvsrepository
Once you've made these group-ownership and permissions changes, your new repository is ready for use and members of your group should be able to import new projects into it, both through the local filesystem and over SSH.
Setting up anonymous CVS access
In addition to the local fileserver and using SSH (or, at other sites, rsh), there's a third method for accessing CVS repositories, the password-authenticated server or ‘pserver’. For reasons of security and scalability, we require the use of SSH for read-write access to CVS repositories stored at Khoury. However, we provide anonymous read-only access to certain CVS repositories using the ‘pserver’ method. In order for that to work, you will need to ask Systems (by sending eMail to email@example.com) to make your project available for anonymous CVS. We'll need the pathname to your project's CVS repository, and the files in that repository need to be world-readable (which they usually already are, of course).
For instance, if you want to provide anonymous read-only access to your project foo, stored in the CVS repository at /proj/myproj/cvs (so the actual pathname to your project files in CVS is /proj/myproj/cvs/foo), you'd just send eMail to firstname.lastname@example.org asking us to make /proj/myproj/cvs/foo available for anonymous CVS. We'd make an appropriate symlink in the /cvs directory on the anonymous CVS server, and remote users could check out your project with the command
[code light="true"] cvs -d :pserver:email@example.com:/cvs checkout foo
The developers in your group, though, will still need to use /proj/myproj/cvs (if they're local) or :ext:login.khoury.northeastern.edu:/proj/myproj/cvs as their repository name for read-write access to the repository.
For more information
This HOWTO is not intended to teach you how to use CVS, but only to show you how to connect to a CVS repository at Khoury over SSH. For a more general introduction to CVS, you might want to consult the following sites and pages:
- http://ximbiot.com/cvs/wiki/: The Ximbiot - CVS Wiki main page.
- http://cvsbook.red-bean.com/: The free chapters of "Open Source Development with CVS".
- http://ximbiot.com/cvs/manual/: The CVS manual.
More information about connecting to Khoury via SSH is available at
- http://www.khoury.northeastern.edu/welcome/: Khoury welcome page.
Also, we will eventually have a document describing how to configure SSH so you don't need to type your password each time you run a cvs command, but that's not ready yet. In the meantime, you might be able to figure it out from the manual pages for ssh-keygen, ssh-agent, and ssh-add, and/or from our Welcome page.