home   about us   solutions   support   writing   link land   discussion forum   feedback   contact us
CVS - A Complete Reference (Client/Server mode)
Overview
Getting CVS
The repository
Multiple Developers
Rolling back to previous version
Some common CVS commands
Other tools and addons to CVS

 

Overview
CVS is a version control system. Using it, you can record the history of your source files. CVS  helps you if you are part of a group of people working on the same project. CVS is mostly used for sharing the same code by multiple developers working togethert. Multiple developers can work on the same project remotely using client server model of CVS where the code exists on central server and each programmer get the source on his local machine(Checkout) from the cvs server and save it back on the cvs server (checkin) after development. Each time a programmer save his code or checkin the code on cvs server , a new version is being created of the same code. This avoids overwriting of code.

This article will explain how to use CVS in client server mode and get the most out of it.

Getting CVS
UNIX
You get cvs server from  http://www.cyclic.com/. Download the newest release of CVS from Cyclic: http://download.cyclic.com/pub/.

Windows 95/NT
Users can pick up the command-line cvs.exe binary here: http://download.cyclic.com/pub/cvs-1.10.5/windows/

The repository
The CVS repository stores a complete copy of all the files and directories which are under version control. Normally, you never access any of the files in the repository directly. Instead, you use CVS commands to get your own copy of the files into a working directory, and then work on that copy. When you've finished a set of changes, you check (or commit) them back into the repository. The repository then contains the changes which you have made, as well as recording exactly what you changed, when you changed it, and other such information.

Creating a Repository
To create a repository, run the cvs init command. It will set up an empty repository in the CVS root specified in the usual way .

cvs -d /usr/local/cvsroot init
Here /usr/local/cvsroot will become the repository.

CVSROOT environment variable
Set your CVSROOT environment variable. If possible, set it once and for all using the Windows control panel, autoexec.bat file, or UNIX script executed on login, such as /.cshrc or
 /.bashrc.

Here's the command line you can use on a Windows 95/NT machine to set up the CVSROOT environment variable. Be sure to put your own username where the example below contains
username.

[c:\] set CVSROOT=:pserver:username@foo.com:/usr/local/cvsroot

Here's the command line you can use on a remote UNIX machine with a bash or sh shell to set up the CVSROOT environment variable. Be sure to put your own username where the
example below contains username.

$ export CVSROOT=:pserver:username@foo.com:/usr/local/cvsroot

If you use a csh shell or the enhanced c-shell tcsh under UNIX on a remote machine, the CVSROOT environment can be set with a command like this:

% setenv CVSROOT ":pserver:username@foo.com:/usr/local/cvsroot"

Backing up Repository
There are a few issues to consider while backing up repository:

  • One should either not use CVS during the backup, or have the backup program lock CVS while doing the backup.
  • To lock CVS, you would create `#cvs.rfl' locks in each repository directory.

Remote Repositories
Your working copy of the sources can be on a different machine than the repository. Using CVS in this manner is known as client/server operation.

Setting up the server:
Put the following entry in /etc/inted.conf on server:

   2401  stream  tcp  nowait  root  /usr/local/bin/cvs  cvs -f --allow-root=/usr/cvsroot pserver

If your inetd wants a symbolic service name instead of a raw port number, then put this in `/etc/services':
   cvspserver      2401/tcp
and put cvspserver instead of 2401 in `inetd.conf'.
Then give a HUP signal to inetd.

Password authentication for remote repository
For remote password authentication put a file `$CVSROOT/CVSROOT/passwd' . The file will look like:

   anonymous:
   kapil:1sOp854gDF3DY
   melissa:tGX1fS8sun6rY:pubcvs

Here password is in unix encrypted form. The first line in the example will grant access to any CVS client attempting to authenticate as user anonymous, no matter what password they use.

The second and third lines will grant access to kapil if he supply his respective plaintext passwords.

The third will grant access to melissa, if she supplies the correct password, but her CVS operations will actually run on the server side under the system user pubcvs.

Note: CVS can be configured to not to check the UNIX real passwd file i.e /etc/passwd for cvs authentication by  setting SystemAuth=no in the CVS `config' file ($CVSROOT/CVSROOT/config).

Using the client with password authentication

You have to login to cvs server for the first time:
cvs -d :pserver:kapil@foo.com:/usr/local/cvsroot login

The you can use all the commands of cvs on the remote machine:
cvs -d :pserver:kapil@foo.com:/usr/local/cvsroot checkout someproj

Read only repository access
It is possible to grant read-only repository access to people using the password-authenticated server. There are two ways to specify read-only access for a user: by inclusion, and by exclusion.
"Inclusion" means listing that user specifically in the `$CVSROOT/CVSROOT/readers' file, which is simply a newline-separated list of users. Here is a sample `readers' file:

kapil
yogesh
john

(Don't forget the newline after the last user.)

"Exclusion" means explicitly listing everyone who has write access--if the file    $CVSROOT/CVSROOT/writers exists, then only those users listed in it have write access, and everyone else has read-only access .The `writers' file has the same format as the `readers' file.

Setting up the files in repository
If the files you want to install in CVS reside in `someproj', and you want them to appear in the repository as `$CVSROOT/someproj', you can do this:

   $ cd someproj
   $ cvs import -m "Imported sources" someproj yoyo start
Here The string `it-action' is a vendor tag, and `start' is a release tag.

CVS locks in repository
Any file in the repository with a name starting with `#cvs.rfl.' is a read lock. Any file in the repository with a name starting with `#cvs.wfl' is a write lock.  The directory `#cvs.lock' serves as a master lock. That means , one must obtain this lock first before creating any of the other locks.

To obtain a readlock, first create the `#cvs.lock' directory. If it fails because the directory already existed, wait for a while and try again. After obtaining the `#cvs.lock' lock, create a file whose name is `#cvs.rfl.' followed by information of your choice (for example, hostname and process identification number). Then remove the `#cvs.lock' directory to release the master lock. Then proceed with reading the repository. When you are done, remove the `#cvs.rfl' file to release the read lock.

To obtain a writelock, first create the `#cvs.lock' directory, as with a readlock. Then check that there are no files whose names start with `#cvs.rfl.'. If there are, remove
`#cvs.lock', wait for a while, and try again. If there are no readers, then create a file whose name is `#cvs.wfl' followed by information of your choice (for example, hostname and
process identification number). Hang on to the `#cvs.lock' lock. Proceed with writing the repository. When you are done, first remove the `#cvs.wfl' file and then the `#cvs.lock'
directory.

Revisions in CVS
You can start a new  or change a existing project from a new rivision number. To set the numeric revisions, the `-r' option to cvs commit is used . The `-r' option implies the `-f' option,which  causes the files to be committed even if they are not modified.
For example, to bring all your files up to revision 3.0 (including those that haven't changed), you might invoke:

   $ cvs commit -r 3.0
Note that the number you specify with `-r' must be larger than any existing revision number.

Multiple Developers

File status
The cvs  status command gives a status about the states of the files. You can get a status of the file by:
cvs status [options] files

Bringing a file up to date
When you want to update or merge a file, use the update command. For files that are not up to date this is roughly equivalent to a checkout command: the newest revision of
the file is extracted from the repository and put in your working directory.
Your modifications to a file are never lost when you use update. If no newer revision exists, running update has no effect. If you have edited the file, and a newer revision is
available, CVS will merge all changes into your working copy.

Resolving Conflicts
It wastes a lot of hours, or maybe days when some developer overwrites the work of another by uploading files without checking for improvements made by other developers. In this section, I will explain  you how to resolve source conflicts.

When you enter the cvs commit command to automatically upload all the files you have changed or added to a project, the cvs repository server may inform you that your locally-edited
 files are not up-to-date with the server or that you need to manually merge one or more files with newer versions that have already been uploaded to the repository by some other developer.
 Here's a sample conflict warning message that occurred during a cvs commit process:

      $ cvs commit
      cvs commit: Examining .
      cvs commit: Up-to-date check failed for `andy.htm'
      cvs commit: Up-to-date check failed for `sample.htm'
      cvs commit: Up-to-date check failed for `index.htm'
      ...
      cvs [commit aborted]: correct above errors first!
 

  You can use the cvs update command to update your local project copy with the latest project on cvs repository. To update your entire working copy of the site, open a command prompt, change to the directory containing the project you're developing, and issue the command:
$ cvs update.
This will update and automatically merge every file that has changed since you last copied over new files from the cvs repository. Line-by-line updates to individual text files (such as HTML files) can often be handled automatically. CVS will list for you any files that require your attention for manual editing and merging.

Examples :
Automatic merge:
You are editing some project file called "index.html" locally and when you try to commit that file to cvs repository then cvs will give you the following error:
$ cvs commit index.html
    cvs commit: Up-to-date check failed for `index.html'
    cvs [commit aborted]: correct above errors first!
This happens because there is a new version of the same file exists on the cvs repository.
Now you can use cvs update command to get the latest version from the cvs repository to your local machine
$ cvs update index.html
    RCS file: /usr/local/cvsroot/index.html,v
    retrieving revision 1.4
    retrieving revision 1.5
    Merging differences between 1.4 and 1.5 into index.html
    M index.htm
After automatic merge process you should check the merged copy to check if it is working properly.
When you are satisfied with the local copy of "index.html" file then you can commit it to cvs
 $ cvs commit index.htm
     Checking in index.htm;
      /usr/local/cvsroot/index.htm,v  <--  index.htm
      new revision: 1.6; previous revision: 1.5
      done

Manual Merge :
In some cases, your recent work on a file might be so different that the CVS needs your manual interference to integrate everyone's work and put it back into the site repository. In this case , merge the files on execution of update command and show the conflicting code with the help of special markers.
$ cvs commit index.html cvs commit: Up-to-date check failed for
      `index.html' cvs [commit aborted]: correct above errors first!

Use the cvs update command to bring your local copy of the site up to date and attempt to automatically merge any changes from other authors:

$ cvs update
cvs update: Updating .
RCS file: /usr/local/cvsroot/index.html,v
retrieving revision 1.5
retrieving revision 1.6
Merging differences between 1.5 and 1.6 into index.htm
rcsmerge: warning: conflicts during merge
cvs update: conflicts found in activity.htm
C index.htm

This time cvs was unable to merge the files automatically and created a special version of the file in conflict and put it in your working copy of the site in place of the original index.html. The special marker line look slike following:
<<<<<<<< filename
To resolve the conflict, simply edit the index.html file and replace the text between the markers and test the file until it works. You should also delete the markers
    <<<<<<<<========>>>>>>>> from the file
After editing the file "index.html" test this file, and use the cvs commit command to put your latest copy of file onto the
  cvs repository:

      $ cvs commit
      Checking in index.html;
      /usr/local/cvsroot/index.html,v  <--  index.html
      new revision: 1.7; previous revision: 1.6
      done

Watches (CVS communication)
cvs can function as a communications device as well as a record-keeper.  A watches feature of CVS  provides multiple developers working on the same project with a way to notify each other about who is working on what files at a given time. By "setting a watch" on a file/directory , a developer can have CVS notify her if anyone else starts to work on that file by means of sending e-mail or some other method.
To use watches you have to edit two files in the repository administrative area. You have to edit the "$CVSROOT/CVSROOT/notify" file (which tells CVS how notifications are to be performed) and "$CVSROOT/CVSROOT/users" file(which supplies external email addresses).
The best way to modify administrative files is to checkout one copy from the repository ,edit them and then checkin to repository .

To specify email notification, first uncomment the following line from "$CVSROOT/CVSROOT/notify" file
ALL mail %s -s "CVS notification"
This command causes notifications to be sent as emails with the subject line CVS notification .

Then you have to create/edit the file "$CVSROOT/CVSROOT/users"
The format of each line in the users file is:

CVS_USERNAME:EMAIL_ADDRESS
For example,
kapil:kapilcool@yahoo.com

The CVS username at the beginning of the line corresponds to a CVS username in CVSROOT/password , or server-side system username of the person running CVS. Following the colon is an external email address to which CVS should send watch notifications for that user.

Email notification with logfile
CVS provides a feature of sending automated email to everyone working on a project  with a log message whenever a commit takes place The program to do the mailing - contrib/log.pl in the CVS source distribution - can be installed anywhere on your system. You ca also installed it into "$CVSROOR/CVSROOT". You should change the following line in log.pl :

$mailcmd = "| Mail -s 'CVS update: $modulepath'";

Once you've setup the log.pl , you can put lines similar to these into your loginfo:

projectteam1 CVSROOT/log.pl %s -f CVSROOT/commitlog -m projectteam1@it-action.com
projectteam2  CVSROOT/log.pl %s -f CVSROOT/commitlog -m projectteam2@it-action.com

The %s expands to the names of the files being committed; the -f option to log.pl takes a file name, to which the log message will be appended (so CVSROOT/commitlog is an ever-growing
file of log messages); and the -m flag takes an email address, to which log.pl will send a message about the commit. The address is usually a mailing list, but you can specify the -m option as
many times as necessary in one log.pl command line.

Some commands related to setting up watches on files:

If you only want to be notified about, say, commits, you can restrict notifications by adjusting your watch with the -a flag (a for action):
$ cvs watch add -a commit hello.c

Or if you want to watch edits and commits but don't care about unedits, you could pass the -a flag twice:
$ cvs watch add -a edit -a commit hello.c

Adding a watch with the -a flag will never cause any of your existing watches to be removed. If you were watching for all three kinds of actions on hello.c, running
$ cvs watch add -a commit hello.c

has no effect - you'll still be a watcher for all three actions. To remove watches, you should run
$ cvs watch remove hello.c

which is similar to add in that, by default, it removes your watches for all three actions. If you pass -a arguments, it removes only the watches you specify:
$ cvs watch remove -a commit hello.c

To find out who is  watching  files - cvs watchers:
$cvs watchers
$cvs watchers hello.c

To find out who is  editing  files - cvs editors:
$cvs editors
$cvs editors hello.c

[Note: It is necessary to run "cvs edit" before editing anyfile to be able to watch feature working.]
To solve this problem  cvs has a feature to remind the  someone to use cvs edit with the help of  the watch on command:
$cd project
$ cvs watch on hello.c

By running cvs watch on hello.c, kapil causes future checkouts of project to create hello.c read-only in the working copy. When someone else  tries to work on it, he'll discover that it's read-only and be reminded to run cvs edit first.
$cvs edit hello.c

Rolling back to previous version
Sometimes you need to revert back to previous version of your  project.  A project under CVS version control can quickly and conveniently revert to an earlier stage of its life. I will explain someof the common examples:
$ cvs checkout -D '1 year ago' preproject
Here preproject is the name of the project.
$ cvs checkout -r1.4 preproject
Here preproject is the name of the project.
 
 

Some common CVS commands

Adding a file to the cvs repository "My_Files"
$ cvs add File3.txt
Now you need to actually upload the file. The previous command just setup the configuration to do it.
$ cvs commit

"cvs commit" will bring you into your default editor, vi or emacs or something else to prompt you to enter a description of your work.. Save the file, and when you quit the editor, cvs will ask you to continue, and select the option to continue. Now you have uploaded a file to the cvs repository "My_Files".

Deleting a file to the cvs repository "My_Files"

In order to delete a file from the cvs repository, do this
$ rm File3.txt
$ cvs remove File3.txt
$ cvs commit

The first step actually deletes the file in your directory. The second step removes it from the configuration of the current directory you are in. The third step commits this
change to the cvs repository"My_Files". If you do not execute "cvs remove File3.txt", you will find it hard to execute "cvs commit" in the future and it won't update the
repository correctly, at least that has been from my experience.

Changing a file to the cvs repository "My_Files"

 Let us add some content to the file File2.txt.

$ ls /var >> File2.txt
$ cvs commit

Removing files
To remove files from a site, you run the cvs remove command on the desired filenames in your working copy. As a ``safeguard'', cvs remove will not work if the files still exist in your
 working copy:
 $ cvs remove file.html
  cvs server: file `file.html' still in working directory
  cvs server: 1 file exists; remove it first
 $

To get around this, you may use the -f option with the cvs remove command:
$ cvs remove -f oldfile.html
cvs server: scheduling `oldfile.html' for removal
cvs server: use 'cvs commit' to remove this file permanently
$
This will not delete the actual files from the CVS server yet, it simply makes a note to tell the server to remove these files the next time you commit your working copy of the project
$ cvs remove [options] files

Removing directories
The way that you remove a directory is to remove all the files in it. You don't remove the directory itself; there is no way to do that. Instead you specify the `-P' option to cvs
update or cvs checkout, which will cause CVS to remove empty directories from working directories. (Note that cvs export always removes empty directories.)
Note that `-P' is implied by the `-r' or `-D' options of checkout. This way CVS will be able to correctly create the directory or not depending on whether the particular version
you are checking out contains any files in that directory.
 

Upload files to the CVS repository

$ cd source
then issue this command
$ cvs import -m "Test Import" My_Files Revision1 start

Download files from CVS

Okay, now we want to download these files into a Working directory .
When we checkout a package from cvs, it will create a directory for us. The parameter "My_Files" that we specified when we uploaded the files into cvs will be the name of
the directory created for us when cvs downloads the package for us.

Now we need to get the cvs package.
$ cvs checkout My_Files

Downloading updates that other people make

If you have downloaded a package from a repository that someone else is maintaining, if you wish to download all the changes, then execute the following command,

$ cvs update -dP

The "d" creates any directories that are or are missing.
The "P" removes any directories that were deleted from the repository.

Viewing the difference
You can easily see the difference between two file using cvs.
       $ cd project
       $ cvs diff index.html
This command runs diff to compare the version of `index.html' that you checked out with your working copy.  Here "project" is the name of the local project directory.

$ cvs diff -r 1.20 -r 1.21 hello.c
This command will show the difference between 2 versiond of same file.

The annotate Command
With annotate, you can see who was the last person to touch each line of a file, and at what revision they touched it. It gives you more information than hostory command:
$cvs annotate

View logs
$ cvs log -r 1.21 hello.c
This will show you the logs for hello.c version 1.21
 

Other tools and addons to CVS

Henner Zeller's CVSweb 
It has a feature of browsing the cvs repository by web browser and even shows the latest revision and log message for each file. It presents you with a web-based interface to browse any and all of the sites and projects you manage by  CVS. You can get it from http://stud.fh-heilbronn.de/~zeller/cgi/cvsweb.cgi/

Martin Cleaver's CVSweb
 It features capabilities for file upload as well as file browsing of cvs repository. You can get this software from http://sourceforge.net/projects/cvswebclient/

LinCVS
A CVS GUI client for Linux. It provides nice feaures and easy to use. You can get it from: http://www.lincvs.org/

WinCVS
A CVS GUI client for windows. It has many good features and I will recommend this software for windows clients. You can get it from http://www.cvsgui.org/download.html
 

This article is Copyright (c) 2000 by Kapil Sharma. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/).

 

Written by: Kapil Sharma
Email:
Website: http://www.linux4biz.net
[Kapil Sharma is a Linux and Internet security consultant. He has been working on various Linux/Unix systems and Internet Security for more than 4 years. He is maintaining a web site http://www.linux4biz.net for providing free as well as commercial support for web, Linux and Unix solutions.]
 

[Back]

Web site maintained & supported by Copyright © Linux4biz.net, 2002-2003