Step-to-step guide to setup a CVS system

This is a step to step guide to setup a CVS system. Far from providing a complete list of options, this guide provides common ways of doing things. So you can quickly start from here and, then, when you feel you need more options, search them in the pretty good documentation that comes with CVS distributions.

CVS overview

CVS is a system used to make the same working files available to several software developers and to keep track to all the versions of each file along the time.

Files are stored on a central repository and each developer has his/her own copy. A developer can change its local copy and when he/she feels it's ok, he/she instructs to the cvs system to apply the changes to the repository.

Files on a repository are grouped by modules. Developers can retrieve and work with a snapshoot of the module as it was at any point of the development history. They can also develop parallel branches of the same module with differents set of changes and later merge them if they need to.

Repositories

Create a repository

The CVS repository is placed on a directory called the cvs root. A clever procedure is to create a cvs administration user and place the cvsroot directory on its home.

  • Install cvs and any cvs front end
  • Create a 'cvs' user with 'cvs' as default group
  • Set cvs user umask to 006
  • Login as 'cvs'
  • Create the '~cvs/cvsroot' directory
  • Check that permisions on '~cvs/cvsroot' are 007
  • Set '~cvs/cvsroot' set gid flag: chmod g+s ~cvs/cvsroot
  • To initialize the repositori, execute: cvs -d ~cvs/cvsroot init

Rationale: The set gid bit asures that all the files placed in this directory will belong to the 'cvs' group, and thus any user that belongs to the 'cvs' group can access those files.

Create alternate repositories in the same machine

Often mantaining two separated repositories in the same machine is useful and it's easy to perform by creating a repository in a different cvs admistrator user home.

  • Create a 'testcvs' user with 'testcvs' as default group
  • Set eviewcvs user umask to 006
  • Login as 'testcvs'
  • Create a '~testcvs/cvsroot' directory
  • Check that permisions on '~testcvs/cvsroot' are 007
  • Set '~testcvs/cvsroot' set gid flag
  • To initialize the repositori, execute: 'cvs -d ~testcvs/cvsroot init'

You can use this alternate repository to cleanly experiment cvs administration commands before applying them to your production repository. Multiple repository is also useful if you want to keep two groups of developers really separated from each other.

Tip: If you have no administator rights on the system to create a new user, you can even create, in your own home, a personal repository to do experimental cvs, or keeping your personal projects on a version control system.

Adding local cvs users

  • You must add the 'user' to 'cvs' group (or 'testcvs' group)
  • Add to the user profile these lines:
    umask 006
    export CVSROOT=~cvs/cvsroot
    

NOTE: This last step will set the default repository for the user. If a user want to access a repository for which the CVSROOT variable is not set, he/she must use the global option '-d mycvsroot' in any cvs command he/she executes.

Working with modules

Creating (importing) a new module onto the repository

Importing is to add a new module onto the repository to work later with it.

  • Login as any local cvs user
  • Create the primordial source file and directory structure
  • Go to the root directory you want to import (you must be in)
  • Execute 'cvs import MyModuleName "MyVendorTag" "MyReleaseTag"'

All the files in the current directory and subdirectories will be imported to the repository as 'MyModuleName'. The vendor tag is a description for the origin the sources files you are importing and the release tag describes the vendor release.

Tip: Once you have done the import you don't have to keep those primordial files any longer on your hard disk

Tip: CVS is somewhat rigid when you want to change names or reestructuring directories. You can't avoid this pain fully but just a little by carefully planing the module structure.

Creating (checking out) a module copy to work with

A sandbox is a module copy that a developer gets from the repository to work with. How to obtain one? Doing a checkout:

  • Login as any local cvs user
  • Go to the directory where you want to dump the working copy
  • Execute 'cvs checkout MyModuleName'

This will create a directory 'MyModuleName' containing all the module files plus some cvs helper files. Each directory on the module has a 'CVS' subdirectory containing those cvs helper files. You must not edit those files.

Working with the local copy

Once you have a local copy you can edit the files as you want. When you are happy with your changes you can commit the changes to the repository.

See Basic CVS usage in order to know how to work with your sandbox. See Managing application releases with CVS to know how to manage a module.

Creating (exporting) a clean copy

For distribution purposes you may not want to include the cvs helper files, so, 'export' is an alternate procedure to 'checkout' that is used to get such clean copy.

  • Login as any local cvs user
  • Go to the directory you want to dump the distribution copy
  • Execute 'cvs export MyModuleName'

Giving access to the outside world

Trusted remote users

A CVS repository has several methods to be reached remotely by developers (pserver, rsh...), but any alternative is inferior to ssh method, so we won't loose time explaining those deficient methods, just ssh based methods.

If you have a ssh deamon running on your cvs server, any user with a valid account can also use cvs remotely without changes on the server. Users only have to define two environment variables on their remote clients systems to have full access to CVS:

export CVSROOT=:ext:yourlogin@server.host:/full/path/to/the/repository
export CVS_RSH=`which ssh`      # or full path to local ssh binary

In this way, remote users will work much the same as if they were on the server, except by the fact they are asked the password on each cvs command. Because this can be anoying, you can use the following trick to automatize the validation:

# From the client side
ssh-keygen -t rsa # Only if you dont have already generated one
cat ~/.ssh/id_rsa.pub | ssh yourlogin@server.host ssh-replacekey

Warning: This method allows the remote user login on the system without further validation. Not only cvs commands. If the client account gets compromised, so does the server account.

TODO: ssh-agent

Untrusted remote users (Jailing CVS)

If you want validated cvs remote users but you don't want give them access to regular login facilities, then you should do some extra work. You should have to put the cvs environment inside a chroot jail.

TODO: jailing

Controling Read/Write Permisions

CVS is unable to control per-file read/write permisions because it completely rewrites the files. So the only control you have is directory permisions.

Security advice: You must handle the CVSROOT module, that contains the cvs administration files, like if it were another different development team, say cvsadm. The problem with that is that with the CVS default configuration uses this directory to place cvs locks, and any user should be able to write in it. So you must change the default cvs configuration.

  • Create a directory outside the cvs root to hold the cvs locks that normally are placed on $CVSROOT/CVSROOT. Do not place inside the cvs root to avoid cvs treating it as a cvs module.
  • Checkout the CVSROOT module
  • Change the LockDir option at the CVSROOT/config to point that directory

Anonymous users

Other CVS documentation

  • The official CVS manual: It provides detailed information about CVS usage. Most CVS distributions bring it on several formats: 'info' pages, html pages, Windows help file... It is also available online.
  • Managing application releases with CVS: It describes a release policy to follow on a project and how to implement it using CVS commands. It is available on my web site as companion of the tutorial you are reading now.