Corrections, comments, and improvements are highly welcome!
CVS (Concurrent Versions System) is a versioning system which manages trees of RCS files. (A very short introductions to RCS can be found here.) These trees are maintained in a single repository, possibly on a remote server. A CVS user creates working copies of some (or all) files and directories of the repository. Working directories are characterized by having a CVS subdirectory.
The focus of this introduction is on the issues peculiar to CVS (as opposed to RCS, software development, etc.). I make no attempt to cover any material which is dealt with in Jim Blandy's Introduction to CVS. You should have read his introduction before proceeding. He covers changing, merging (including conflict handling), and committing files. He also mentions some worthy conventions, like committing log entries which describe the reason for a change. (Maybe these two documents should be merged some day?)
Some of the information in this document is taken from Open Source Development with CVS and other parts are from the famous Cederqvist Manual.
This document only discusses the command line interface for Linux/BSD/Unix systems. This makes it easier to understand what is actually going on. I had big problems with WinCVS until I studied the Unix commands for CVS.
cvs -globaloptions command -commandoptions arguments
When referring to a cvs command I am mostly referring to
command from the above line.
-d :pserver:yourlogin@nil.ics.uci.edu:/home/cvs/REPOSITORYwith your cvs commands.
cvs login
and provide your user password for nil.
(Don't forget the -d option in case you are using the first method.)
mkdir new_working_dir
cd new_working_dir
cvs checkout .
or you can can create copies of top-level subdirectories and modules like this:
cvs checkout dir_relative_to_cvsroot
cvs checkout module
(The role of modules will be explained later.)
In contrast to the files and directories in the repository, your copies are called
working files and they are located in their working directories.
The repository on nil has currently the following directory structure:
/home/REPOSITORY/
lagoona/
texmf/
www/
transprose/
prototypes/
mr.brown/
pag/
arithmeticencoding/
visions/
mr.blond/
mr.blue/
mr.brown/
mr.orange/
mr.pink/
mr.white/
well/
www/
index.html
users/
phf/
cs/
more users to come
Sadly, some of these directories are still empty!
cd working_dir
cvs update
This command updates all the files in the directories rooted at
working_dir.
It does not create new working directories even if these might
have been created in the repository since the last update occurred.
All directories are created upon update like this:
cvs update -d
This weird behavior is more a feature than a bug (though -d
should maybe be the default) because it allows the programmer to tell CVS
not to update certain directories simply by removing the working copy of it.
The best convention seems to be to put at least one file into every live directory and to use
cvs update -dP
for all updates.
The -P stands for 'purge' and removes all empty working directories
which are also empty in the repository.
Note: Don't confuse update and checkout. Technically, the difference is that update expects to be run for an already checked-out working directory, e.g., using the cvs server information in the CVS subdirectory, whereas checkout will create new root directories. (See the Cederqvist Manual (Section A.7) for some quirks of checkout.) For a start, update -d should always be sufficient.
cd working_dir
mkdir newdir
cvs add newdir
cd working_dir
... create newfile ...
cvs add newfile
cvs commit
cd working_dir
rm working_file
cvs remove working_file
With the next
cvs commit
the deletion becomes manifest in the repository.
cvs release -d working_dir
This command checks for any uncommited changes and asks you if you
want to release and delete (that's what the -d stands for)
your working directory working_dir.
You can give `.' as the working_dir
(which makes sense if your $CVSROOT does not point to the
repository of the directory you wish to release).
This will delete your current working directory.
So don't be surprised.
cvs update -rmajor.minor file
This retrieves version major.minor of file.
One thing is special here. Revisions like this are sticky.
That is, when you do your next regular update (without the -r option),
CVS will still remember to update to version major.minor.
In order to revert to the old behavior of always updating to the current HEAD you must issue:
cvs update -A
cvs tag branchname-root
cvs tag -b branchname-branch
cvs update -r branchname-branch
...edit working copy...
cvs tag branchname-1
...edit working copy...
cvs tag branchname-2
...and so on.
in dir of trunk working copy
cvs update -j branchname-1
cvs commit -m "merged branch up to branchname-1"
cvs tag merged-branchname-1
...edit working copy...
cvs update -j branchname-1 -j branchname-2
cvs commit -m "merged branch up to branchname-2"
cvs tag merged-branchname-2
...and so on.
in dir of branch working copy
cvs update -j merged-branchname-2 -j trunktag1
cvs commit -m "synchronized with trunk up to trunktag1 (from merged-branchname-2)"
cvs tag synced-trunktag1
...edit working copy...
cvs update -j trunktag1 -j trunktag2
cvs commit -m "synchronized with trunk up to trunktag2 (from trunktag1)"
cvs tag synced-trunktag2
...and so on.
It seems that you can not merge and sync a branch alternatingly without permanently causing merge conflicts. If somebody knows how to do this, please mail me!
rm oldfile1 oldfile2 ...
cvs remove oldfile1 oldfile2 ...
cvs commit -m "moved from here to there" oldfile1 oldfile2 ...
In order to permanentely change the permissions of a working copy file, it seems to be necessary to change the files permissions directly (!) on the repository's ,v copy of that file, e.g., from non-executable to executable. (If anybody knows of a better way, please email me.)
cvs admin -kb switch for binaries (i.e., no keyword substitution and no RCS deltas?). It might require folks to check out from scratch. More to come here.
cd dir_from_which_to_import
cvs import -m "what you import" rep_dir_relative_to_cvsroot vendorname releasetag
The
rep_dir_relative_to_cvsrootdirectory will be created if it doesn't exit already.
The
vendornameand
releasetagarguments specify where you got the code from and which release it is. (Internally the imported files are also checked in on the vendor branch by default 1.1.1 .) This gives you the opportunity to track different vendor releases without mixing up their changes with yours. See Cederqvist for details.
No working copy is created.
importonly operates on the repository. Do a regular
checkoutin order to create your working copy.
(In contrast to RCS tags, CVS tags are not allowed to start with numbers. Therefore it is a good idea to re-tag the relevant files while still under RCS.)
If you already have a project which you maintained with RCS then you are likely
to want to preserve your rcs logs.
This is the only instance where you want to operate directely on the server's
copy of the repository.
If you feel uncomfortable doing that ask me or Peter Fröhlich about it.
Basically, you have to create the directory of your project in the repository
by hand (either directly on the server or via cvs add dir).
Next, the rcs files (the ones ending in ,v) are copied to their
destination directly.
With
cd dir
cvs update -d
you can immediately retrieve your working copy.
cvs history -e -a
Shows repository's history of everything and for all.
In order to see who changed a certain line of code last do:
cvs annotate file
cvs -d repdir init
and create cvs group and make prospective users members of this group.
Don't forget to change ownership of repdir (recursively).
$CVSROOT/CVSROOT/passwd on the server allows to define new passwords
for cvs access only.
The only occations on which direct manipulation of the repositories content should be necessary is the import of files under RCS and copying of files while maintaining their version history.
(It also seems necessary to change file permissions in the repository, once they have been checked in incorrectly.)
$Id: intro.html,v 1.15 2001/05/30 13:49:13 cst Exp $