Managing and tracking changes made to code, otherwise known as version control, is vital to any software project, large or small. CVS, the Concurrent Versions System, is one change management application. This is a summary of how to use CVS in an environment with servers running both Unix and Microsoft Windows operating systems.
Some of CVS’s advantages are:
- CVS is open source, free software
- It can support multiple platforms simultaneously
- CVS uses standard SSH for access to the code repository
- CVS is easy to use and simple to manage
The CVS Repository
All of the software managed under CVS is housed in a repository. Individual projects under CVS control are each stored in a top-level directory inside of the repository. These directories are known as modules. To take full advantage of CVS, each project must be stored under a single directory. If different sections of a project are stored in seperate modules, they won’t be controlled as a single unit.
The file and directory structure of the repository mirrors the actual code.
A file, say
filename.txt, is stored in CVS as
Each file’s complete history is stored inside of its CVS file.
A user of CVS checks out a copy of a project from the repository. This copy is known as a sandbox. This term reflects that the copy has no direct influence on the central repository. The sandbox can be deleted, moved, or altered at will. Also, changes made to the code in the repository won’t affect the sandbox immediately. The owner of the sandbox controls when it is updated with any new changes from the repository, and also decides when any alterations to the sandbox are checked back into the central server.
To use CVS, the application itself needs to be installed on both the repository server and the client computer. The client computer is any physical server where a copy of the controlled software will reside.
Also, the server and its clients need a way to securely communicate. The SSH protocol is well-established and the easiest way to set up a CVS network.
The CVSROOT environmental variable tells the CVS application
the repository location and how to connect to the repository server.
For example, if CVSROOT is set to
it means that the CVS repository is externally located on the achilles
server in the /home/cvs directory. CVS should log into achilles as
the kecarang user.
Installing CVS on a Windows workstation
Under the Microsoft Windows operating systems, there are a few of different ways to gain access to the CVS commands. Both CVS and OpenSSH can be installed as part of the Cygwin Unix emulation package. Those users comfortable with Unix-style terminal sessions and commands will probably find this entirely adequate for everyday use. It is the simplest and fastest way to get CVS running on Windows:
- Cygwin - http://www.cygwin.com
A second Windows CVS implementation is TortoiseCVS. It allow you to work with files under CVS control directly from Windows Explorer. TortoiseCVS automatically installs its own SSH client as well.
- TortoiseCVS - http://www.tortoisecvs.org
There is also a graphical front-end for CVS. The Microsoft Windows version is known as WinCVS . WinCVS comes with a shell that allows the user to enter CVS commands directly. It requires Python to be installed.
WinCVS requires an SSH client program be installed. Cygwin’s version of OpenSSH, the open source SSH package, can be installed standalone from the SSHWindows project.
- SSHWindows - http://sshwindows.sourceforge.net/download/
Setting Up the CVS Repository
The following notes are for the repository server’s administrator. Users can skip down to the next section.
The CVS repository is the central area where all the controlled source code lives. While CVS clients can freely run any number of operating systems, the server should be running under a Unix-based OS. CVS was developed for Unix and therefore many aspects of the application rely on its superior file security and processing features.
For our purposes, all users with CVS access are members of the cvs group. Usernames are restricted to eight characters, and will mirror the employees’ NT sign-on. For example, Keith Carangelo’s NT sign-on is KECARANGEL (limited to ten characters). His username on Achilles would be kecarang (eight characters, all lowercase letters).
Use the following commands to add a user (and that user to the cvs group):
# adduser kecarang # adduser kecarang cvs
If the new user is only going to use CVS and doesn’t require a login shell on the repository server, generate an SSH public/private key pair for him. Do not enter a passphrase.
# su - kecarang $ mkdir -p .ssh $ ssh-keygen -trsa -f .ssh/id_rsa $ cat .ssh/id_rsa.pub >> .ssh/authorized_keys2 $ chmod 640 .ssh/authorized_keys2
Now, move the private key to the client computer. Open a command window (Start -> Run, Open: cmd):
> c: > cd "Documents and Settings\kecarangel" > mkdir .ssh > cd .ssh > scp kecarang@achilles:~/.ssh/id_rsa .
Access to the CVS repository server
$CVSROOT environmental variable tells the CVS application
the location of the code repository and how to connect to it. For
example, setting CVSROOT to
tells CVS that the repository is externally located on the
host, achilles, that it should login to achilles as
user kecarang, and that the repository is in the /home/cvs
Individual CVS users need to access the repository server. Authorization can be validated using either passwords or public/private keypairs. This is analogous to clients using either passwords or digital certificates to access websites secured with the SSL protocol.
The most important CVS commands are: importing existing, non-controlled code into CVS, checking code out of and back in to the repository, keeping the client sandbox up to date, and tracking code changes.
Importing existing projects
The CVS command for importing existing code into a module is:
$ cd <project_dir> $ cvs import -m "Comment" <project_name> vendor start
The vendor and start arguments are generic. They are required, but not useful for our purposes. This project is now ready to be checked-out. Move the uncontrolled directory out of the way, and replace it by checking out the module:
$ cd ../<project_dir> $ mv <project_dir> <project_dir>.bak $ cvs co <project_name> $ rm -rf <project_dir>.bak
Code management commands
Projects are checked out of the repository using the co command:
$ cvs co mymodule
Changes made to a project can be checked in to the repository all at once or on an individual file basis:
$ cd mymodule $ cvs ci -m 'Check in changes made to a single file' myfile.txt $ cvs ci -m 'Check in any and all changes to this project'
The -m denotes a comment that is recoded in the file history log.
The update command ensures that a sandbox has the latest copy of the code from the repository:
$ cd mymodule $ cvs update
Tracking code changes
The log command gives a history of the changes made to an individual file. This includes the version number, author, date, and comment for each change.
$ cvs update myfile.txt
View differences between separate versions of a file using the diff command:
$ cvs diff -w myfile.txt $ cvs diff -w -r1.10 -r1.8 myfile.txt
The -r parameter denotes a specific version of the file. If it isn’t present, the current version of the file is assumed.
Usually, changes in whitespace aren’t significant, and can be ignored using the -w option.
Other CVS tips
Add the following line to controlled source files (using the appropriate comment line delimiter. For Perl files, it is the pound sign, ‘#’):
# $Id: cvs_notes.txt,v 1.5 2006-03-15 16:42:41 caran Exp $
When the file is subsequently checked out of the repository, the
$Id: cvs_notes.txt,v 1.5 2006-03-15 16:42:41 caran Exp $ block
will expand to show the file name and the latest version number, author,
# $Id: cvs_notes.txt,v 1.5 2006-03-15 16:42:41 caran Exp $
When adding a large, pre-existing project into CVS, you may find files (or whole directories) that don’t require source control, such as log files or temporary objects. You can use the .cvsignore file to instruct CVS to ignore files and subdirectories, even before the project is imported into CVS! Create the .cvsignore file and add the ignorable objects, each on a separate line:
logs error_log.txt *.wrk
The .cvsignore file uses the asterisk (*) as the ‘match everything’ and the question mark (?) as the ‘match any single character’ wildcards.
You can also use the cvs import command to add new directories below an already existing project. Using the example above, assume that a new directory needs to be added under myproj:
# cd newdir # cvs import -m 'Added newdir to myproj' myproj/newdir vendor start
Email notification of repository changes
From Top 10 CVS Tips on the O’Reilly website:
To send an email when changes are committed to the repository, add a line like this to the $CVSROOT/loginfo file:
DEFAULT mail -s %s firstname.lastname@example.org
You can even configure loginfo to run a script, instead. This is useful to send messages to multiple email addresses. See the log.pl program that comes as part of the CVS source distribution.
Last Updated: Wed, 05 Oct 2005