A Simple Primer on How to Use the Command cvs... Craig C. Douglas April 2, 2006

A Simple Primer on How to Use the Command cvs in a Project
Craig C. Douglas
April 2, 2006
1. Preface
This is an informal document. It is intended to provide techniques that work on the day that I
wrote this document versus being a formal document for all time. What I have documented here
works for me, works for my colleagues, and works for some random strangers who take classes
from me that I want to guarantee an always working environment for. I do not claim that what I
describe in this document works anywhere else or for anyone else or at any given time (past,
present, or future). The See No-cvs, Hear No-cvs, Speak No-cvs philosophy is the motto of this
document.
In §2, introductory material is given. In §3, a sample repository is defined and what you need to
access it. In §4, a number of cvs commands are defined. In §5, how to use multiple repositories is
described. In §6, final thoughts are given.
As more people read this document, I receive questions that by answering in this document makes
it more complete and better. I make certain assumptions about what the reader knows that is not
always correct. This means that even extremely basic questions sometimes are not answered here,
but should be. If you do not understand something here, please contact me so that I can make it
better.
2. Introduction
The version control system cvs has been around for many years. It is used in many, many group
projects and is readily available on many operating systems including all Linux-like systems, Mac
OS X, and Windows (Cygwin-like systems). A newer system called subversion will eventually
replace cvs in most open source projects. However, cvs is a very mature program and has many
users who can help you if you get stuck.
Projects are maintained in cvs repositories, using the standard cvs jargon. A repository is a set of
directories, each of which is considered a project at the top level of the directory hierarchy.
Throughout this document, cvs commands are suggested. The cvs commands are always run on
your local computer. You might not ever log directly into the computer that has the actual cvs
repository stored on it. Always work on the computer you normally would.
Sometimes it is useful to use more than one cvs repository. This complication is discussed in the
§5. If you have never used cvs before, learn first by using only one repository.
Once you have checked out your project once (which is described two pages hence, sorry about
that), you can make life a lot easier for yourself. First do not ever quite delete the whole project.
If the project is called project, never delete the project/bin directory. You can refer to files in this
directory to get definitions useful to accessing your project when you log into a computer.
In projects that I give to students or colleagues, I always create a default project that has both bin
and doc directories. In the bin directory are two important files:
project/bin/env.csh
project/bin/env.sh
Environment variables suitable for csh or tcsh
Environment variables suitable for sh, bash, or ksh
These files cannot be executed by a Linux (or Linux-like) shell program, but must be sourced or
included by your shell program. You should create (or add to) your .tcshrc or .profile the
following:
source project/bin/env.csh
. project /bin/env.sh
If you do not know how to use an editor just use the following two commands:
echo ‘project /bin/env.csh’ >> ~/.tcshrc
echo ‘. project /bin/env.sh’ >> ~/.profile
Log out and the next time you login the definitions will be part of your working environment
automatically.
In the doc directory are the following files:
doc/cvs-primer.doc
doc/cvs-primer.pdf
The Word document
The PDF version of the Word document
There are lots of places on the web to find better documentation than this document. I use
http://www.cs.utah.edu/dept/old/texinfo/cvs/cvs_toc.html
http://www.delorie.com/gnu/docs/cvs/cvs_toc.html
I almost always find the answer to my questions on this site.
The O’Reilly book on cvs is a real gem if you want to know how to do all sorts of things with a
repository, particulary when you need debug it when subtle things go completely awry with
obscure and inscrutable error messages.
I am going to assume throughout the rest of this document that you are using a Linux-like
operating system (I am writing this using Word 2004 and Mac OS/X 10.4). I will use standard
Linux-like notation and commands that require a terminal or command line window.
There are graphical user interfaces to cvs, which you can investigate. Some of my students swear
by Eclipse, which can be downloaded from http://www.eclipse.org, which is an open source
development system that runs on Linux, Macs, and Windows. Once you get your eclipse to
understand where your cvs repository is, lots of things become automatic and simple.
3. A Sample Repository
In this section a location will be specified in the environment variable CVSROOT. This is a
generic (and not likely to exist) location. For one of my classes, you have to use the definition
that I will email you. I never post the actual location due to computer security concerns. Please do
not post the location either.
Consider the following definitions in bin/env.csh:
setenv
setenv
setenv
CVSROOT
CVSEDITOR
CVS_RSH
www.foo.org:/u/cvsroot
vi
ssh
What does this gibberish mean? CVSROOT is the location on the Internet of the repository. In
this case, it is on the machine www.foo.org in the directory /u/cvsroot. Every time you modify
the project in the repository, you will have to document what you are doing using an editor. In
this case, you are using the vi editor. Almost any editor will work fine, so feel free to use
whatever one you like that can write a plain text file. Finally, you must connect to the
repository’s computer using a secure shell program so that passwords are encoded, not in clear
text. There are many ssh implementations for all current operating systems (see
http://www.openssh.org for a list).
Incorporating the environment definitions for CVS is dependent on which shell you use. Using
tcsh or csh, you incorporate these definitions into your current environment using the command
source bin/env.csh
This can be typed by hand or the definitions can be put into your ~/.cshrc or ~/.tcsh file. Using
bash, sh, or ksh, you incorporate these definitions into your current environment using the
command
. bin/env.sh
This can be typed by hand or the definitions can be put into your ~/.profile file.
4. Using cvs Commands
4.1. Checking Out a Project
Suppose you are working on a collaborative project called Uh-oh. If you want to get a copy to
work on, just type
cvs checkout project
or
cvs co project
(they are equivalent). You will have a new directory called project. You do not have exclusive
rights to the files. Anyone else with the correct permissions can check out your project and
modify it at the same time. Be careful of conflicts. If you have a conflict, you must resolve the
conflicts by hand. Do not just delete the other person’s changes or you will probably have a very
mad coworker (and rightfully so) whose time you just wasted.
4.2. Commiting Changes for a Project
Once you have modified, added, or deleted files and/or directories in a project, you can make the
changes to the repository. Be careful, however. Just type
cvs commit
And cvs will walk through all of the subdirectories committing all changes that it knows about.
4.3. Updating Your Copy of a Project
If you have already checked out a copy of project Uh-oh and you want to keep it up to date, just
type
cvs update -d
in the Uh-oh directory. If you have added subdirectories, you can do an update on just one of the
subdirectories (and all of its subdirectories) the same way. The –d parameter will also create new
subdirectories that have been added to the repository since you last did a cvs update. If you do not
want to get new subdirectories, leave the –d off the command.
It is a good idea to do an update as soon as you start working on a project again after any sort of
break. If you are certain that you have not changed anything since you last committed changes,
you should consider simply checking out the project again. Also, before committing things, it is a
good idea to do a cvs update -d first in order to see if any conflicts exist, and fix them before
trying to do an unsuccessful cvs commit.
The output from cvs update –d is cryptic to say the least. Below you will find a list of what the
single characters probably mean that are prepended before file names printed on your screen by
cvs:
Output
U file
P file
A file
R file
M file
C file
Meaning
The file was brought up to date with respect to the repository. This
is done for any file that exists in the repository but not in your
source, and for files that you have not changed, but are not the
most recent versions available in the repository.
Like U, but the CVS server sends a patch instead of an entire file.
This accomplishes the same thing as U using less bandwidth.
The file has been added to your private copy of the sources and
will be added to the source repository when you run cvs commit on
the file. This is a reminder to you that the file needs to be
committed.
The file has been removed from your private copy of the sources
and will be removed from the source repository when you run cvs
commit on the file. This is a reminder to you that the file needs to
be committed.
The file is modified in your working directory. This means (1)
there were modifications in the repository as well as in your copy,
but they were merged successfully without conflict, in your
working directory, or (2) there were no modifications to the same
file in the repository, so that your file remains as you last saw it. It
is a good idea to inspect any file with this tag.
A conflict was detected while trying to merge your changes to file
with changes from the source repository. The copy of file in your
working directory is now the result of attempting to merge the two
revisions. An unmodified copy of your file is also in your working
directory, with the name `.#file.revision' where revision is the
Output
? file
Meaning
revision that your modified file started from. You must resolve the
conflict yourself (or with the help of others using the repository).
Do not just step on your coworkers modifications unless you can
outrun a group of people with torches, tar, feathers, and a waiting
pot of boiling oil.
While file is in your working directory, it does not correspond to
anything in the source repository, and is not in the list of files for
cvs to ignore.
There may be other symbols that cvs may use with a file or directory name, but these are the
common ones.
A quick check on which files are out of date in your directory can be determined using
cvs -n -q update
There are other techniques for checking your files list in §4.10 and §4.11.
4.4. Adding a File to Your Project
This is easy. Create all of the files that you want to add in a directory. Then just type
cvs add files
Note that none of the files will actually be added to the repository until you do a cvs commit. Do
not forget the cvs commit once you are convinced of the validity of your addition. If you do
forget, no one will be able to get the new files since they were not formally added to your
repository.
4.5. Adding a Directory to Your Project
Directories are painful to add to a cvs repository, unfortunately. First you have to add the
directory, then all of the files in it. Type the following:
cvs add dir_name
date >dir_name/.Created
cvs add dir_name/.Created
cvs commit dir_name
I know this is ridiculous. However, cvs refuses to add an empty directory to a repository unless
there is an option that I am unaware of (which is highly possible).
This really ought to add the directory and the .Created file to the cvs repository. Next add any
files that you want to dir_name, use cvs add on those files, and do another cvs commit.
4.6. Deleteing a File from Your Project
This one of the places that cvs shines brightly. You can delete a file, but it never actually goes
away. You can get it back by backing out of commits. This is tricky, but can be done. Not that I
ever have done this myself, but I have heard of lots of people who have…  Before deleting a
file, make certain that if it is modified that you commit the changes to the repository first. So,
just type
rm files
cvs delete files
cvs commit files
and after the cvs commit, the files appear to have been deleted from the repository.
4.7. Deleting a Directory from Your Project
You cannot actually delete a directory except by tricking cvs. Delete all of the files in the
directory (as just described) and ignore the directory. If it is completely empty, the next time you
checkout your project, the directory will not be there.
4.8. Moving a File, but Not a Directory
This is really obscure until you think about it and see the simplicity cvs employs. Just type
mv Old_file New_file
cvs delete Old_file
cvs add New_file
cvs commit –m “Move Old_file to New_file” Old_file New_file
Do not move directories. It usually requires changes to the repository itself. This might require
the help of the owner of the repository, who will not want to spend time helping you do this
operation.
4.9. Backing Out of Changes
Buy the O’Reilly book on cvs if you really want to learn how to move forwards and backwards
through changes with any real hope of being successful. You need to become an expert on
branching, revisions, and history tracking. The info cvs command can help get you started, but
the O’Reilly book is the best source of information. It even has some examples in it.
4.10. Status of Your Copy of Your Project
You can check the status of all of your files using the command
cvs status
A few lines of information about each file and directory will be printed. No files change in the
process.
The following line will display all files that are not up to date without actually changing anything
in your working directory.
cvs -n -q update
It provides a quick check of project activity, potentially by others.
4.11. Log of Changes to Your Project
You can find out about all of the changes made to a file or project using either
cvs log file
cvs log
Be prepared for a lot of lines of output. It is a good idea to pipe the output through the less
command (e.g., cvs log | less) or redirect the output to a file (e.g., cvs log > some_file).
You can also get creative and check the log for many files or directories at once.
5. Working with Multiple cvs Repositories
This is actually easy to do as long as you are methodical about keeping track of your CVS
environment variables. In §3, we worked with one repository. We used the tcsh or bash
commands
source env.csh
or
. env.sh
to set environment variables needed to access one repository. Suppose we have stored two
repositories in directories in our home directories (the home directory is represented by ~/ below).
Then the repositories are in the two directories,
~/cvs-rep1
~/cvs-rep2
with the env.csh and env.sh files in
~/cvs-rep1/bin
~/cvs-rep2/bin
respectively. You can define aliases as follows for a tcsh or bash shell:
alias cvs-rep1 ‘source ~/cvs-rep1/bin/env.csh’
alias cvs-rep2 ‘source ~/cvs-rep2/bin/env.csh’
or
alias cvs-rep1 ‘. ~/cvs-rep1/bin/env.sh’
alias cvs-rep2 ‘. ~/cvs-rep2/bin/env.sh’
To access the cvs-rep1 repository, use the command
cvs-rep1
Once you use this command, all accesses to a cvs repository will be to the cvs-rep1 one.
Similarly, to access the cvs-rep2 repository, use the command
cvs-rep2
Simply use either cvs-rep1 or cvs-rep2 before using any cvs command if you are not absolutely
sure which repository you are accessing currently.
6. Final Thoughts
There are many, many more options to cvs that I am not going to comment on. You can find
more on any Linux-like system by typing the command
info cvs
and working your way through the menus. Hosting multiple projects is easy in a repository using
the import option. Hosting multiple cvs repositories on a single machine is also easy using
multiple definitions of env.csh and env.sh.
The most important thing to remember is that you should communicate regularly with your
colleagues who are working on the same project at the same time. Just once having to sort out a
conflict (which someone does by hand comparing files a line at a time) will convince you never,
ever to voluntarily do it again.
When irresolvable cvs problems occur, send e-mail to the poor person running the repository. I
can assure you from experience that that person will happily wait as long as you want to try to fix
the problem yourself before hearing from you. Good luck.