CVS
--
EladLahav - 25 Nov 2005
Preamble
CVS is an easy to use, yet powerful and effective version control system. It is based on a client-server architecture that stores all files in a common place, thus allowing several people to collaborate on a project.
Terminology
Common terms used by CVS:
- Repository: A collection of file and directory revisions managed by CVS. A repository is stored on the server-side.
- Module: A project managed by CVS. A module is simply a directory in a CVS repository.
- Tree: A snapshot of a module stored on the client-side.
- Root: A string containing the access method, user name and path leading to a CVS repository.
- Import: Populating a newly created module with files.
- Checkout: The process of creating a tree in a work directory.
- Update: Synchronising a tree so that it reflects the current state of the repository.
- Commit: Synchronising a tree so that changes in the work directory are applied to the repository.
CVS Life Cycle
Working with CVS usually involves the following stages:
- Create a module in the repository and import files into it.
- Create (check-out) and maintain (update) a tree in a work directory.
- Work on your tree.
- Transfer (commit) your changes.
We shall assume that a repository was already created and that it is accessed only through rsh/ssh. The root will be
:ext:elahav@hopper:/u3/elahav/cvsroot
where
:ext:
means that the repository can only be accessed using rsh,
elahav
is the user name,
hopper
is the server on which the repository resides and
/u3/elahav/cvsroot
is the path to the repository.
- Note
- To use ssh instead of rsh, set the environment variable
CVS_RSH
to ssh
.
Every CVS command has the following form:
cvs CVS_OPTIONS COMMAND COMMAND_OPTIONS
Most CVS commands work recursively, which means they are applied to all sub-directories.
Import
The import process creates a new module in the repository. The module is populated with all files in the current directory. The command has the following syntax:
cvs -d ROOT import MODULE_NAME VENDOR_TAG START_TAG
where
ROOT
is the repository's root string,
MODULE_NAME
is simply the name of the module, and VENDOR_TAG and START_TAG are arbitrary symbols.
- Note
- You can get rid of the
-d ROOT
part by setting the CVSROOT
environment variable to the root string.
- Note
- The vendor and start tags are just relics from old times. You can safely use the strings VENDOR and START for every module you create.
Assume
~/src/myproject
is a directory containing the files to import. The following commands create the module
myproject
in the repository
cd ~/src/myproject
cvs -d :ext:elahav@hopper:/u3/elahav/cvsroot import myproject VENDOR START
Alternatively, we can use the
CVSROOT
environment variable:
export CVSROOT=:ext:elahav@hopper:/u3/elahav/cvsroot
cd ~/src/myproject
cvs import myproject VENDOR START
Since CVS works recursively, all sub-directories and their files will also be imported.
Checkout
The checkout command creates a tree by copying the latest version of all files in a module into a the current directory. Its basic syntax is:
cvs -d ROOT co MODULE_NAME
Checkout can also create the tree in a specified directory:
cvs -d ROOT co -d DIR MODULE_NAME
For example, to check out the
myproject
module in the current directory
cvs -d :ext:elahav@hopper:/u3/elahav/cvsroot co myproject
or, if
CVSROOT
has already been set correctly
cvs co myproject
This command creates a directory called
myproject
under the current directory, populated with the module files (including all sub-directories). Each directory in the tree has a CVS sub-directory, which contains such information as the name of the module, its root and the files in this directory that are included in the module.
Once the module has been checked out, you can work on the files in the tree directory. This will not affect the repository in any way.
- Note
- There is no concept of "locking files" in CVS (as opposed to e.g., RCS).
Update
While working on your local tree, some changes may occur in the repository. For example, someone else may have changed some files, or even you may have done so from another tree (for instance, when working from your home computer). It is therefore advisable to update the tree as often as possible. Maintaining an updated tree will reduce the risk of conflicts that arise when several people are changing the same code.
To update the entire tree, simply move to the tree's top-most directory, and issue the command
cvs up
For example, in order to update the
myproject
tree kept in
~/src
, run the commands
cd ~/src/myproject
cvs up
The tree is update recursively, so there is no need to issue the command again for each sub-directory. Note, also, that you do not need to specify the root in the update command, as the
CVS
sub-directory contains a
Root
file that is read automatically.
One can also update any sub-directory of the tree, by changing to that directory and running the
cvs up
command.
When CVS updates the tree, it outputs the names of any modified files and indicates their status. This status is given by any of the following letters:
- U: This file was not in your tree, and was fetched from the repository.
- P: The file exists in your tree, but had to be patched in order to update it to the latest version.
- M: The file in your tree contains local changes (that were not yet committed to the repository).
- C: The file was changed both locally and in the repository, resulting in conflicts. Conflicts need to be resolved manually.
- ?: A local file is not part of the module (you can ignore this message).
Commit
Once your changes were made and tested, you are ready to incorporate them into the repository. This is done using the command
cvs commit FILE1 FILE2 FILE3 ...
This command requires you to explicitly provide the names of the modified files you would like to commit. Once the command is issued, an editor session will begin, which you can use to write a log entry describing the changes made to these files. If you want a different log message for each file, you need to run the
commit
command separately. The files are committed once you save the contents and quit the editor (e.g., using
wq
in Vi). Note that lines in this file beginning with "CVS" are comments, and are not saved as part of the log entry.
- Note
- You can skip the editor session by supplying the log entry with the
-m
switch, e.g.,
cvs commit -m "This is my informative log entry" hello.c hello.h
Add/Remove Files
If you add files to your tree, and would like these files to also be added to the module, use
cvs add FILE1 FILE2 FILE3 ...
Similarly, to remove files from the module use
cvs remove FILE1 FILE2 FILE3 ...
None of these changes take effect until you issue a
commit
command including these files.
For example, to add
foo.c
and
bar.h
to
myproject
, issue the commands
cvs add foo.c bar.h
cvs commit foo.c bar.h
GUI Clients
While CVS is pretty simple and can be easily operated from the command line, it is sometimes more convenient to use a GUI client instead. Here are some suggestions of clients available for different environments:
- LinCVS is a multi-platform client for Windows, Mac OS X and Linux.
- CvsGui have different clients (the Mac OS and Linux clients are somewhat outdated).
- Cervisia is a very good client that is distributed as part of KDE.
More Help
To learn more about the CVS command line options, use
cvs --help
or
cvs -H COMMAND
for details on the specific commands (such as
import
,
co
,
up
,
commit
, etc.). Under Unix, the
man
command should give you more details.
Documentation is available on the CVS main
website and in
this manual.
The Subscription Website and CVS
Repository Information
- Repository
-
asimov.cscf:/projects/research/cvsroot
- Module
-
sub
- Access method
- SSH (
:ext:
)
Versioning Scheme and Tags
We follow a
Major.
Minor versioning scheme for production versions. For ecample, the current version number is 3.0, the next minor changes (bug fixes and small features) will appear in version 3.1, and the next overhaul will result in version 4.0.
Before a version is released for production, it undergoes a Release Candidate (RC) phase, during which it is publicly tested. Release candidate versions have the same number as the future production version, with -RC
N appended, where
N denotes the current revision. For example, the first release candidate for version 3.0 is 3.0-RC1, the second is 3.0-RC2, etc. Once a release candidate has been approved to be of production quality, the RC number is dropped, and the version is moved as-is to the production directory.
CVS tags for the production versions follow the scheme
V_Major_Minor
. Thus version 3.0 is associated with the CVS tag
V_3_0
. For release candidates, the suffix
_RCN
is added, e.g.,
V_3_0_RC4
for the fourth release candidate of version 3.0.
Deploying a New Version
We keep three folders under the Research Subscription website:
- Development (
subdev
)
- Release candidate (
subRC
)
- Production (
sub
)
The
subdev
directory always points to the
HEAD
version of the CVS tree, while
subRC
and
sub
contain tagged versions. Deploying a new version is therefore only a matter of updating the relevant directory. For example, to upgrade the RC directory to version 3.0-RC2, use:
research$ export CVS_RSH=ssh
research$ cd subRC
subRC$ cvs up -r V_3_0_RC2
subRC$ ./fixperm
(note that the
fixperm
script needs to be called to set the correct permissions for the different files.)
Similarly, the following commands upgrade the production version to 3.1:
research$ export CVS_RSH=ssh
research$ cd sub
subRC$ cvs up -r V_3_1
subRC$ ./fixperm
Usually
sub
and
subRC
should not be modified in any other way. However, if, for some reason, a new
sub
or
subRC
directory need to be created, the code should be checked out from the CVS repository, and the files
.options
and
.rtoptions
should be copied into the new directory. (These two files contain user-configurable information, and are therefore not part of the CVS module. They can be fetched from a backup of the old
sub
or
subRC
directory.)
In the following example, a new subRC directory is created:
research$ export CVS_RSH=ssh
reseacrh$ cvs -d :ext:elahav@asimov.cscf:/projects/research/cvsroot co -r V_3_0_RC1 -d subRC sub
research$ cd subRC
subRC$ cp .snapshot/nightly.0/.options .
subRC$ cp .snapshot/nightly.0/.rtoptions .
subRC$ ./fixperm