CVS for Dummies
Bernd Loechner, Andreas Jaeger
Table of Contents
Introduction
Files like source code or documentation are frequently changed.
In addition to that, many files of different versions are being
worked on by several developers at the same time. CVS provides
powerful support for tasks of this kind. This article is intended to
present a brief insight into CVS to those who are
"new" to this topic (the so-called dummies) or
who only use CVS once in a while.
This article is by no means a complete documentation.
It is meant to introduce the basic concepts and commands of CVS.
Motivation
Anyone working on software development (i.e. on source code)
or documentations is familiar with the following situation:
Documents are being worked on by many several developers for
a certain period of time. Soon the following problems will arise:
How to perform an undo operation on the documents? How to
reestablish the document's status from April 29, 2000? Or how
to keep track of all changes that have been applied to the
document (meaning: when was which change applied and by whom)?
You would have to consider the different versions of a
file and their interconnections. So, copies of these files
need to be made in order to document the changes that have been applied
to them. The best is to use a versions management tool
specially designed for this purpose. This tool will no longer keep the
different versions of a document, but will archive the changes between
the versions. Versions are identified by their version
number.
An increasing number of developers complicates this task. On one
hand, it should be possible for them to work independently of each other,
on the other hand, the version management system needs to make sure that
changes do not get lost during the course of development.
The Basic Approach of CVS
CVS ("Concurrent Versions System ") is a version management system.
It is a GNU product meaning it is freely available. And it is capable of managing
huge projects, a large number of files and developers.
For CVS, a project is just a normal UNIX file tree containing the
files. At a central place, all versions of the files are stored
together with the change logs. This is the so-called repository.
Normally, only source files are kept under CVS, generated files like
those resulting from translation by C (*.o), Java
(*.class*), or LaTeX (*.dvi) are not kept under
CVS. Every user may have local copies of the data and work on
them as usual. This can be done independently of the other developers.
CVS does not include any kind of locking mechanism (RCS does, for
example).
After local changes have been approved, they can be copied into the
global directory (repository). CVS will provide a record of the user
who did the changes, the date etc. Furthermore, it makes sure
that changes by several users are integrated appropriately, provided
they do not overlap. CVS cannot check these changes for logical correctness.
It can only check for syntactical collisions. Therefore, each developer has to bear
the sole responsibility for his changes (i.e. whether they are useful
and whether the code is still compilable).
Note: "CVS is not a substitute for developer
communication." [P. Cederquist]
The Use of CVS
CVS can be used to administer files of any kind, but its main focus
lies on text files. Their format does not matter to CVS, it will handle
HTML, LaTeX or different kinds of source code without any problems.
The authors may use CVS for voluminous text files (such as
dissertations), web sites and bulky software packages. Project sizes
can range from small (one single developer or just a few of them) to
huge with several hundreds of developers involved.
Write access to these projects may be limited to just a few of them, but
everyone can access a project under CVS via an anonymous read-only access.
So everyone interested in a project may keep track of the development and
contribute to the relevant mailing lists.
CVS has become a standard tool for many open source developers.
Most of the GNU projects, including the GNU Compiler Collection can be accessed via CVS.
Naturally, as an open source project CVS itself is under CVS (see http://www.cvshome.org). At Sourceforge, more than
12000 software packages are maintained using CVS. Projects like KDE, Gnome, and Mozilla are also under
CVS.
Further Documentation
Quite detailed help pages concerning CVS can be accessed by
info cvs and using the Emacs (and XEmacs) command
C-h i. Of course, you may browse the CVS man pages
(man cvs), too.
Short help texts on CVS can be invoked using:
cvs --help
cvs --help-commands
If you need help concerning specific commands, try:
cvs --help kommando
Karl Fogel's "Open Source Development with CVS", published by
(Coriolis (ISBN 1-57610-490-7)) provides
a deep insight into CVS and gives an introduction to Open Source
Development and quite a lot of helpful hints on project
management.
Look up the official CVS pages for
the CVS sources and further documentation.
Important Commands
CVS commands are given as parameters of the UNIX program cvs.
Commands can only be executed one at a time. The order of the parameters is
important. In most cases, you will not need to specify any further options,
a function call will normally look like this
cvs command [<filename>]
With no filename given, the command is executed in the current directory and
its subdirectories. A filename may contain path information.
Some Preparations
Adjust your working environment appropriately before you start working with CVS.
Environment Variables
CVS makes use of numerous environment variables. For ordinary use, just
remember setting CVSROOT, CVSUMASK
and CVSEDITOR.
The path directing to the global CVS directory is specified by CVSROOT.
Commands like checkout, import and init will not work
without this specification. Alternatively, the option
-d <directory> can be added to each command.
CVSUMASK determines the right of access to any file in the global directory.
It should contain access to "group".
CVSEDITOR specifies the editor that will be started when cvs commit
is executed.
In the user's ~/.bashrc, these variables can be defined as follows:
export CVSROOT /cvsroot
export CVSUMASK 003
export CVSEDITOR 'emacs -nw'
Configuration Files
In a .cvsignore you store some examples of filenames which should be
ignored by CVS. For Java, choose to ignore all .class files. This can either
be achieved by creating a global .cvsignore file in your home directory or by
adding a .cvsignore to the appropriate CVS directory.
A global .cvsignore in your home directory may just contain:
*.class
It might be useful (at least for certain commands) to include their
standard parameters in ~/.cvsrc . At least, you should include:
update -d
Following an update, new directories in the repository will be included in the current
directory instead of being ignored otherwise.
Creating a Work Copy
Create a work copy of any project before you start working on it under CVS.
CVS needs this copy to determine the correlation between the global version and your
local one later on. Using the command:
cvs checkout <modulname>
creates an up-to-date copy of the project in a subdirectory of the
same name in the current directory.
For this purpose, a project needs to be put under CVS first. See
section "Creating a Project" for more details.
Synchronizing Changes
In case, there are several developers working on the same project,
their changes need to be synchronized from time to time. Your own files
can be synchronized with the changes of your colleagues by:
cvs update
cvs update imports the global changes to your local copies.
If the local copy has not been changed, the global changes are applied to them
without any further problem. In case your own changes and the global ones do
not overlap, the global changes are applied to your local copies without
overwriting the changes you applied locally. Conflicting changes (local vs. global)
are both included into your local files. This might look like this:
...
<<<<<<< filename
... local text ...
=======
... global text ...
>>>>>>> 1.3
...
CVS gives the following warning:
cvs update: Updating .
RCS file: /home/aj/cvsroot/Test/filename,v
retrieving revision 1.2
retrieving revision 1.3
Merging differences between 1.2 and 1.3 into filename
rcsmerge: warning: conflicts during merge
cvs update: conflicts found in filename
Conflicts then have to be resolved one by one manually.
Your own changes are made globally accessible by cvs commit.
Please determine whether this should happen to one file only, to a group of files
or to all files that have been changed so far, because the commit messages will
be the same for all changes. So their content should make sense.
A single file is checked in by:
cvs commit <filename>
For more than one file, just add the list of filenames to the cvs commit
command. In order to make all changes globally available, you should use:
cvs commit
cvs commit will only be excuted after the global changes have been applied
locally and potential conflicts have been resolved appropriately.
It is therefore useful to perform cvs update before each cvs commit.
CVS itself will give this advice though.
Differences between global and local version are determined by:
cvs diff <filename>
Add the appropriate version numbers, then you get the differences between
these versions displayed by:
cvs diff -r1.1 -r1.5 <filename>
cvs commit invokes the editor specified in CVSEDITOR
in order to create the commit message. A commit message allows you to keeep track
of all the changes that have been applied. Alternatively, you may choose to
add a commit message by cvs commit -m "message" <filename>
via the command line. You get a list of all commit messages using:
cvs log <filename>
Registering New Files
In case you want to insert a new file to your existing project,
create the new file in your local directory. Tell CVS that
you want to version control this file, using:
cvs add <filename>
The actual check-in (to the global repository) is done by:
cvs commit <filename>
New subdirectories are created and put under CVS the same way.
Deleting Files
Deletion of a file is performed similar to the creation of a
new file. First, a local rm deletes the file in your local
directory. Then you tell CVS that you want to delete this file:
cvs delete <filename>
Finally, you delete this file globally using:
cvs commit <filename>
The file will be deleted in the global project under cvsroot.
CVS will keep a backup copy of the old version in a special directory under
cvsroot.
Placing Version Information in the Source Code
CVS allows you to annotate version information directly to a file.
In order to achieve this, some of the following keywords need to be put
into the text. They will be replaced appropriately during the
check-in/check-out procedure. $Author$ will give the author,
$Date$ the date of the last revision, $Revision$
the version number, and $Log$ will give a complete proheadlineol
of the changes that have been applied so far.
$Id$ summarizes the most important information.
Applying this concept to source code of programs means to hide
this kind of information in the comments section or - in case they
should also be present in the compiled version - to create strings.
Under LaTeX, the rcs.sty (which can be found under
ftp://ftp.dante.de/tex-archive/macros/latex/contrib/supported/rcs/) provides
a comfortable way to access this information.
Handling CVS with Emacs/XEmacs
Newer versions of Emacs and XEmacs support CVS via VC
(version control) - preferably on file level. The most important command is C-x v v.
Alternatively, VC can be accessed via the Tools menu.
A Few Additions
These commands are not for daily use, but nevertheless they are of some importance :)
Creating a Global CVS Directory
After CVSROOT has been set, a global CVS directory for the
repository can be created and initialized using
cvs init
This has to be done before any other operation is executed.
Creating a Project
A global directory can contain several projects. CVS treats each project as a tree.
To put an already existing tree as a project under the control of CVS, you need to change
to the top level of the existing tree and execute
cvs import <modulname> <vendor-tag> <release-tag>
<modulname> refers to the root directory of the
new project. The complete tree will be copied to this directory in the global
directory. Locally, the tree remains unchanged. To start an entirely new project without
any files, create a new, empty directory, change your working directory to the new directory
and execute cvs import. <vendor-tag> and
<release-tag> are used to specify this import.
Normally, they can be set to dummy values.
Look out! In order to allow future modifications of a project under CVS, it is
essential to check it out by:
cvs checkout <modulname>
Locale and Remote CVS Directories
CVS can be set up in several different ways. Normally, CVSROOT
has the following format :METHOD:USER@MACHINE:/cvs/root/directory.
Appropriate default settings are used in case METHOD,
USER@ or USER@MACHINE have been left out.
Local access to a CVS directory means giving access to this directory to all
developers via the local network (e.g. via NFS). This method is referred to as
"local". The CVSROOT variable may be set to :local:/cvsroot
or to /cvsroot (:local: is optional).
In order to allow access to CVS directories from remote stations, you could either
set up a dedicated CVS server or allow access by rsh or ssh. For smaller
projects with only a few developers or with an anonymous access, the CVS server is
preferred. The method is pserver, so CVSROOT is set to
:pserver:anoncvs@anoncvs.cygnus.com:/cvs/gcc, for example.
Accessing a CVS dirctory by rsh makes use of the ext method.
In case encrypted access is preferred, try ssh. This is the normal way
for Open Source developers to access their projects (with write access).
In order to enable ssh access, the environment variable CVS_RSH
has to be set to ssh. CVSROOT may then take the value of
:ext:cvs.x86-64.org:/cvsroot.
Building Releases
A release is a (consistent) snapshot of the entire project.
It should always be possible to reconstruct this snapshot in the following
phase of development. A release should be made, at least when an important
stage of development has been accomplished.
This is not trivial, since at a given date, file 1 might have the
version number 1.17. but file 2 1.78. To complicate matters, files
might later get deleted or added. Releases are not specified by
numbering, but by symbolic names like alpha, beta
and special-version-for-Bernd etc. A release is made by
typing
cvs tag <release>.
To check out a given release, execute
cvs checkout -r <release> <modulname>.
Bernd Löchner is currently working on his PhD of Computer
Sciences at the University of Kaiserslautern. His main focus lies on
automatic theorem proving and program transformation.
Andreas Jaeger used to work together with him on several projects. He is now working at the
SUSE Labs. There he uses CVS during his daily work on glibc and
GCC.
|