Using CVS

Version: $Id: cvs.html,v 1.16 2001/10/12 14:22:24 hans Exp $

This document describes the Concurrent Version System (CVS) usage and conventions.
Internet CVS documentation, manuals, a good presentation, and for the impatient a FAQ.


1. Introduction
2. Requirements
2.1. Remote CVS Access via passwords
2.2. Remote CVS Access via SSH / RSH
2.3. Other settings
3. Initializing your development directory
4. Editing files
5. Adding new files and directories
6. Last intro part: Hints
7. Adding Karma to new users
8. Deleting files
9. Renaming files
10. Deleting directories
11. Viewing status and history
12. Viewing multiple-file diffs belonging to one commit action
13. Importing vendor sources
14. Updating vendor sources
15. Reviving files
16. Tagging
17. Renaming vendor branches
18. Branching

1. Introduction

CVS is a version control system. Using it, you can record the history of your (source) files. If you want to know more read this and this as I'm not going to paste it all here.

2. Requirements

First you have to choose your CVS access method.
  1. If you want to use windows (WinCVS), you must use the 'Remote CVS Access via passwords' method. See also the Quick Reference WinCVS document. You can use the same method for your Unix based CVS access too.

  2. If you want to access CVS from Unix machines, or directly from the Internet, you must use 'Remote CVS Access via SSH'.
Note: you cannot easily mix these two methods on one checked out tree. Contact Hans if you really want to.

2.1. Remote CVS Access via passwords

In ~/.login:
    setenv CVSROOT ""
    echo "====> CVSROOT set to $CVSROOT"
And do a cvs login once. This will create a ~/.cvspass file with your encrypted password.

2.2. Remote CVS Access via SSH / RSH

In ~/.login:
    setenv CVSROOT ""
    setenv CVS_RSH "ssh"
    echo "====> CVSROOT set to $CVSROOT"
Note: when you do not want to use SSH, use RSH. Note also that RSH is not available from the internet as it is insecure.

For RSH, add a

    <yourhost> <usercode>
line in your ~/.rhosts file, and perform a chmod 600.

For SSH, set it up first, this is not yet documented. But when you have ssh-agent forwarding working, nothing more is required :-)

2.3. Other settings

Please, please, please create a ~/.cvsrc file:
    update -d
    diff -u
    cvs -q
which gives some default parameters to the 'cvs update' and 'cvs diff' commands. 'update -d' is important, 'diff -u' is a matter of taste, 'cvs -q' causes cvs to be somewhat less verbose.

3. Initializing your development directory

To initialize your own development directory use:
    cd ~
    mkdir develop
    cd develop
    cvs co source
    cvs co lib
    cvs co intranet
Please note that you only have to do this ONCE !

The `cvs co' (check-out) will create your own source and intranet web pages working directories. It contains directories called CVS where some CVS administration is done, never change these CVS-directories or the files in them if you do not know what you're doing!

4. Editing files

After the initial `cvs co' you can immediately start developing with the files.

When you have finished editing you can commit your changes to the general repository with

    cvs commit
This command can be given at top-level (~/develop) or at a lower level; it will always do all subdirectories too, unless explicit file names and/or directory names are given as parameters after `cvs commit'. This is the behavior for (almost) all cvs commands.

Please be careful with commits, use

    cvs update
first to find out which files would be committed when you would do a 'cvs commit'

You will be asked to describe your changes; as editor the editor mentioned in the environment variable `EDITOR' will be used (default vi, override in your .login file if necessary). All lines in the commit template file starting with `CVS' are removed automagically from the final commit message and are only for reference purposes. Format your commit message such that the line length is less than 72 characters; exceptions are made for cut'n'paste'd lines of logfiles/programs.

After you have described your changes save the file and exit the editor. A commit message will be mailed to the development group. When committing many files at once in different directories it is possible to use one description for all changed files by answering '!' at the appropriate question.

Do not wait too long (i.e., days or weeks) before committing your changes, because otherwise somebody else may have changed the files which could lead to CVS conflicts. If you are uncertain whether you have the latest version you can always use

    cvs update
This will resynchronize your development tree and the repository. Also watch commit mails from other developers to see if they are working in the same area which could lead to conflicts.

To view the differences between your (changed) working copy of a file and the last version in the repository use:

    cvs diff filename
For better readable output use a `-u' option after `diff' (can also be stored in your ~/.cvsrc). cvs diff also works for directories and without any further arguments it show the differences of all files in the current directory and all directories below it.

5. Adding new files and directories

Make sure a file has the correct chmod settings in your own development directory: chmod 755 (rwxr-xr-x) for a script/executable, 644 (rw-r--r--) for a normal file. For a directory 755 should be used.

New files/directories can be added with

    cvs add filename
    cvs add directoryname
Then, an explicit
    cvs commit
is necessary to really add the file to the repository; for directories it is done (and mail is sent) automatically.

Binary files must be added with

    cvs add -kb binary_filename
This can still be done afterwards with
    cvs admin -kb binary_filename

Note that one cannot use 'cvs add *' because the 'CVS' directory itself will then be added as well.

6. Last intro part: Hints

Congratulations, you are ready with the intro

7. Adding Karma to new users

New users need to be added by the CVS administrator to some files, follow the next procedure:

Private develop server:

  1. add username to avail in your checked out CVSROOT directory
  2. 'cvs commit avail'
  3. add user's workstation to various .htaccess files and commit them
Repository server:
  1. execute 'co avail,v' in /home/cvs/CVSROOT on the repository server
  2. become root and add user's workstation to /etc/hosts.allow
  3. add user's email address to committers alias in /etc/aliases and rerun 'newaliases'
  4. add user's account to the cvs group in /etc/group

8. Deleting files

To remove a file:
    rm filename
    cvs delete filename
An explicit `cvs commit' is necessary to really delete the file from the repository. (Well, ok, move to the 'attic' ;-) not really delete)

The full revision history of the file will be kept.

9. Renaming files

You have two options, option 2 is the preferred one.
  1. In your checked-out directory rename the file and do a 'cvs delete oldfilename' and a 'cvs add newfilename' followed by a commit. This is the easy way, but it has annoying limitations: you loose all of the file's revision history ! This is not what we want.

  2. Use 'cvs surgery'. Go to the repository on repo:/home/cvs and copy the oldfilename,v to newfilename,v then go to your own checked-out directory and do a 'cvs update'; you will check out the newfilename, then do a remove oldfilename followed by a 'cvs delete oldfilename'. And of course a commit. This method implies more work, but you get to keep all the file's revision history as an award. If you are uncertain how to do this then contact a repository master who will do the move in the CVS repository for you.

10. Deleting directories

Directories cannot be removed from the CVS repository other then by CVS surgery and manual intervention in the personal working directories of all developers. If this happens, mail must be sent to all developers saying which actions they have to perform in their own working directory.

11. Viewing status and history

To view the status of a file use 'cvs status filename'. Example:
    File: cvs.html          Status: Locally Modified

       Working revision:    1.18    Wed Apr 22 15:17:30 1998
       Repository revision: 1.18    /home/cvs/intranet/conventions/cvs.html,v
       Sticky Tag:          (none)
       Sticky Date:         (none)
       Sticky Options:      (none)
The 'Sticky' things should normally be '(none)', unless development branches are created. 'cvs status' also works for directories and can be used without arguments so it shows the status of a whole directory tree.

To view the history of a file use 'cvs log filename'. Example:

    RCS file: /home/cvs/intranet/index.html,v
    Working file: index.html
    head: 1.5
    locks: strict
    access list:
    symbolic names:
    keyword substitution: kv
    total revisions: 5;     selected revisions: 5
    revision 1.5
    date: 2000/03/08 13:47:25;  author: hans;  state: Exp;  lines: +3 -3
    fix telephone link
    revision 1.4
    date: 2000/03/08 09:58:21;  author: hans;  state: Exp;  lines: +4 -4
    add link to cvsweb
RCS is the underlying mechanism for CVS. Times are logged in UTC (GMT).

12. Viewing multiple-file diffs belonging to one commit action

For a CVS-1.10 server you need to lookup the commit in the commitlogs in /home/cvs/CVSROOT/commitlogs/.

You'll find something like :

Then do for each file listed a diff from the previous version to the one listed :
cvs diff -uw -kk -r1.6 -r1.7 source/a/b/Makegile
cvs diff -uw -kk -r1.5 -r1.6 source/a/c/source.c
Note 1 : if the file originates from a vendor branch you might want to replace the first -r revision with the vendor branch revision. You then use something like :
cvs diff -uw -kk -r1.1.1.3 -r1.6 source/a/vendor/othersource.c
Note 2 : you might want to use the symbolic version name if you want to diff against the vendor branch. You then use something like :
cvs diff -uw -kk -rV2_3_3 -r1.7 source/a/vendor/othersource.c
Note 3 : when you want to diff everything against the latest vendor branch, do something like this:
cvs diff -uw -kk -rV2_3_3

13. Importing vendor sources

Importing sources is like adding sources, but in such a way that the vendor releases can be tracked and integrated easily while still allowing local modifications to the sources when necessary.

  1. Extract the sources in a temporary directory and chdir to this directory. (E.g. cd ~/tmp/ ; tar zxf ~/py152.tgz ; cd Python-1.5.2/ )

  2. Remove possible existing CVS / RCS directories in the vendor sources :
    find . -name CVS -print | xargs rm -fr
    find . -name RCS -print | xargs rm -fr

  3. Make sure all files are readable for everyone :
    chmod -R +r *

  4. Import the sources :
    cvs import extern/python/distribution PYTHON V1_5_2
    And change python in the appropriate vendor module name, PYTHON in the appropriate vendor module name, V1_5_2 in the appropriate version (replace . with _)

    NOTE: paste the 'cvs import' line in your commit mail, it is an excellent place to log the used vendor module name.

14. Updating vendor sources

Note: PYTHON example used. Old vendor release is V1_5_2, new one is V1_5_3.
  1. Do a 'cvs update' in your own develop directory, this is crucial as it cannot be done lateron.
    cd ~/develop/extern/python/distribution
    cvs update

  2. Then perform the actions for 'Importing vendor sources', with only the vendor module name updated (V1_5_3 for our example). Use your cvs mail archive to find the previously used vendor module name, or use 'cvs log' on a file in the distribution/ directory. If you are lucky you get a 'No conflicts created by this import'.

  3. Now you need to import the vendor changes in your own tree :
    cd ~/develop/extern/python/distribution
    cvs update -jV1_5_2 -jV1_5_3
  4. Manually edit all files that were modified (M) or had conflicts (C) in the update process. (possibly there are none, the only things that can cause conflicts here are our own changes to the vendor sources, or already existing CVS tags in the sources)

  5. Check your changes, they must be relative to the latest vendor release.
    cd ~/develop/extern/python/distribution
    cvs diff -rV1_5_3
  6. Commit your changes. Now others can cvs update their own trees.
    cd ~/develop/extern/python/distribution
    cvs commit

15. Reviving files

This should be implemented some day as 'cvs undelete'.

There are two solutions, one that deals with cvs surgery and one that does not which we show first :

  1. cvs status initrender_ext.h gives Repository revision: 1.2, subtract by one for the next action:
  2. cvs update -p -r 1.1 initrender_ext.h > initrender_ext.h
  3. cvs add initrender_ext.h
  4. cvs commit initrender_ext.h
And the cvs-surgery one:

To revive a file which was removed by a 'cvs delete', move the file from the 'original-directory'/Attic directory in the CVS repository to the directory above. Then use 'rlog file,v' to get the latest revision number (let's say it is X.Y), the 'state:' for that revision will be 'dead'. Revive the file using the following command:

rcs -sExp:X.Y file,v
After this a 'cvs update' in your own working directory should make the file reappear.

16. Tagging

With tags you can more easily restore a complete old version. This will be possible with, for example in a new directory, 'cvs checkout -r release-2-0-1 source' (note that this will create sticky tags, that is a 'cvs update' will not update to the HEAD branch, unless a 'cvs update -A' is given first)

Tags are needed anyway if we decide to start using branches (needed when we want a development branch next to a patches branch after a new release was made) (I hope we can postpone this branching, it is quite complicated)

We use the following naming standard:

    blender-creator-<version numbers>-release
    blender-publisher-<version numbers>-beta
with <version numbers> the number from the VERSION file with the '.' replaced with '-'. Example for a whole tree like develop/source, develop/lib, develop/release :
    cd ~/develop/source/ && cvs tag blender-creator-2-22-release
The release manager will be the one performing these tagging actions.

17. Renaming vendor branches

NOTE: this should be done by an experienced CVS user.

Sometimes the maintainer of a product changes, in that case it is nice if we can rename the vendor branch accordingly.

cd distribution
cvs admin -nNEW_NAME:1.1.1 .
cvs admin -nOLD_NAME       .
The vendor tag name will now appear at the top of the symbolic names listing in 'cvs log'.

Note: we assume that 1.1.1 is the vendor branch.

18. Branching

NOTE: this should be done by an experienced CVS user.

Here we describe how a branch can be created.