I wrote the following parpagraph back in 2005, and now that it is 2016, you really ought to be using GIT, plain and simple. CVS and SVN are all things of the past. This guide was written back in 1999.
Well, as of 2005, you really should think about not using cvs at all and using subversion instead, and I have a set of notes on subversion also.
CVS is the "concurrent version system" - which is a popular and freely available tool for source code management. I have been using it for several years now to manage my own projects, and find it to be an indispensible part of the way I develop software. It has seriously saved my bacon on several occasions.
This page is my own personal "cheat-sheet" for using CVS.
To get the whole story, you really should refer to the
real documentation, but perhaps this will help you get
going with CVS.
If you are reading a printed copy, you can go to the online
copy (with working links) at
http://cholla.mmto.org/computers/cvs
The current CVS home page seems to be: the CVS home page
A source for additional information is here: CVS resources
CVS has a wonderful and detailed manual
(the PDF version is 184 pages).
I keep copies of the manual in
pdf
format, as a
bundle
of html files for you to download, and in
html
format for you to peruse.
You may want to visit the CVS main site to see if more up to date versions of the documentation have become available. These are appropo to cvs version 1.11.2 which may be shipping with Red Hat Linux 7.3.
Another great resource is the CVS intro pages at Sourceforge. It was through these that I learned about the book by Karl Fogel Open Source Development with CVS parts of which are available online at: red bean. Chapter 1 comes highly recommended.
Long ago, I used RCS (upon which early versions of CVS were based), but frankly I doubt if anyone uses RCS anymore (or SCCS either for that matter), so I won't spend any time contrasting the two. Suffice it to say that CVS is one of the flagship free software efforts and was the clear choice until subversion came along to do version control even better.
The primary benefits that I appreciate are:
CVS is supposed to be good for allowing multiple developers to work on a project, but I haven't put that facility to use. I have sort of misused it as a software distribution tool. I develop code on my desktop machine, then use CVS to update other machines where the code is used (this is chiefly useful for scripting languages where the source code is the executable).
Here are some links to resources on the WWW.
Graphical (and other) front ends to CVS abound, and tend to come and go. There was a project called "GIC" (Graphical interface to CVS) which has now been abandoned with interest being redirected to TkCVS.
First of all I have set up my CVS repository on mmt: as
/home/tom/CVSarchive
Once upon a time, long ago I did:
Then, somewhere along the way, I began using multiple repositories and was worried about all hell breaking loose, so I deleted this forcing myself to explicitly indicate the repository when necessary. It turns out that "when necessary" is only at checkout time for all practical purposes. In this case, use something like this:
cvs -d machine:CVSarchive checkout project
In the scheme above, proj_name is identical to project (the name of the directory holding the project. After confirming that the cvs checkout has regurgitated the project, the directory project.ORIG can be deleted. The import/checkout cycle is important (or nice anyway) since it gets the starting "image" of the project into the repository and sets the $Id$ stuff in the file headers.
To get changes from the repository in your working copy, do this:
To add or remove a file:
CVS works nicely with entire directory trees. Let us say that bigproject is a directory with many subdirectories under it, the following command puts the whole mess into the repository:
An import of a new addition to a directory tree (e.g. a whole new project) can be done. It is important to remember that the project name given on the import command is the path within the repository where the addition will go, and that the import should be issued while in the project directory. An example follows where "Drivers/dir1 is the path within the repository where a new directory will go:
New files and directories can be added to an existing project in just the way you might expect.
I have found modules and tags to be handy tools. The process for creating modules is a bit zany, you have to checkout a file called CVSROOT/modules, edit it, and then commit it. Here is an example:
The -l switch says not to log anything to the history file, this might allow a readonly access to the CVS archive, for folks that just want to get a copy of the source, but do not have write access to the repository.
Notice that a cvs release -d is done to get rid of the working directory. This both deletes the files, and does cleanup so CVS doesn't worry about them any longer. Apparently without the -d, CVS is told to forget about it, but you still have the files to fool with.
Right now I have the following modules defined in CVSarchive:
To get a specific version of a single file: (which you will only very rarely want to do).
Really helpful is the -D command, saying to do a checkout or update as of what was current as of a given date:
Beware! When you pull a version out like this, it gets pulled with a sticky date. You will not be able to commit to the archive until this is cleared. You clear it by doing a cvs update -A command. There are a variety of ways to shoot yourself in the foot here (maybe you should extract to stdout using the -p switch) What I do is something like this (which gives you 3 versions to try to sort out):
To move the repository is simple on one hand, but has some tricky issues on the other. The easy way would probably be to commit everything to the repository and entirely delete all working directories. Then tar up the repository and copy the tarball onto the new machine that will host it. Untar it there, then set up the environment variable CVSROOT to point to the new repository, then check everything back out.
I didn't do the business of checking everything in and nuking my working directories. It turns out that in the CVS directory of every working directory (and all subdirectories thereof) there is a file called Root that typically contains one line which isthe value of CVSROOT at the time the working directory is checked out. This value is then used for all commit and update activity, NOT the value of CVSROOT. So if you do what I did, you need to go in and edit the machine name in this file which is easy but tedious.
Remote CVS is definitely a useful thing. Here is how it works. First you decide on some machine being the repository machine. It doesn't require any special setup, but of course it has the repository on the local disk and is able to run plain old CVS. Clients must have rsh (or ssh) access to the server machine (perhaps set up by a .rhosts file), and must be able to run cvs. On the client machine, the CVSROOT environment variable is set to server_machine:dir, and then things just work. No special CVS protocol is involved here, rsh/ssh protocols do all the work.
A special note at this point,
it is possible (and quite desirable)
to access the CVS server via ssh.
This can be done by setting the CVS_RSH environment
variable to the path to the remote shell executable,
in this case:
CVS_RSH=/usr/bin/ssh; export CVS_RSH
Beyond simple rsh access, there is "pserver" which can be extended to provide anonymous cvs access (some large software projects are now using this to make their development trees publicly accessible). This is a notion of what is required to do this, I have yet to get brave enough (or to find sufficient motivation) to try this. A client may do something like this:
The above is just the simplest case of many schemes that can be used. Just to give a view of what is possible, consider the following. Alternate "methods" may be used to access the archive, and some schemes may involve passwords, aliasing of users to a CVS user namespace, kerberos, adding an entry for CVS to the inetd.conf files and /etc/services and so on, ultimately allowing full access only to selected users, and read-only access to others, and perhaps no access to yet others.