Introduction À CVS

Sébastien J. Gross

16 mai 2001 version 0.0.0


CVS (Concurrent Version System) permet une simplification de la gestion de projets pour le travail en groupe, conserve l'historique de toute les modification effectuée sur un fichier permettant ainsi une traçabilité totale. Brian Fitzpatrick en dit: «Je ne peux pas imaginer programmer sans... Ce serait comme faire du parachutisme sans parachute».

1. Diffusion du présent document

Ce document est sous licence FDL.

2. Installation de CVS

2.1 À partir des packages

Sur Debian, il suffit de lancer la commande suivante, après avoir créé un répertoire pour le repository (par défaut /var/cvsroot):

        # apt-get install cvs
		
Répondre au questions posées (notamment pour le répertoire par défaut du repository)

Sur Redhat, Mandrake, SuSE... la commande suivante devrait faire l'affaire:

        # rpm -i cvs-version.rpm
		

Pensez à remplacer version par le numéro de version.

2.2 À partir des sources

Il faut d'abord télécharger les sources depuis le site officiel de CVS et lancer la compilation:

        $ tar xfz cvs-version.tar.gz
        $ cd cvs-version
        $ ./configure
        $ make
        # make install
		

Voilà, maintenant CVS devrait être disponible sur votre machine.

3. Configuration de CVS

3.1 Création du repository local

Le repository est l'endroit physique où se trouvent les fichiers du projet su le serveur. Il peut se trouver n'importe où sur votre machine. Dans cet exemple, un seul repository sera localisé dans /CVS, pour cela il faut créer ce répertoire:

        # mkdir /CVS
        # cd CVS
		

Pour fonctionner correctement, CVS a besoin d'une variable d'environnement ($CVSROOT). Avec un système fonctionnant sous bash ou zsh, il faudra lancer la commande suivante:

        # export CVSROOT=/CVS
		

Par contre avec un csh ou tcsh, il faudra lancer la commande:

        #setenv CVSROOT /CVS
		

Attention: $CVSROOT doit absolument être en absolue pour un fonctionnement correct.

Ensuite, il faut initialiser le repository, toujours dans le répertoire /CVS:

        # cvs init
		

Cette commande se charge de créer un sous-répertoire CVSROOT de /CVS qui contient des fichiers que les plus curieux pourront aller voir, mais qui dépasse le cadre de cette introduction (du moins pour le moment).

3.2 Configuration du serveur CVS

CVS peut fonctionner soit en mode local, soit en réseau. Pour le fonctionnement en local, rien n'est nécessaire suite à l'installation. Pour le faire fonctionner un réseau, quelques modification sont à effectuer dans le fichier /etc/ined.conf. CVS fonctionne sur le port pserver (parfois nommé cvspserver). Par défaut, le numéro 2401 est attribué à ce port. Pour que vote machine fonctionne en tant que serveur CVS, il faut lui dire d'écouter sur ce port. C'est inetd qui s'occupe de tout ça. Dans votre fichier /etc/ined.conf, rajoutez la ligne suivante:

        pserver stream  tcp     nowait  root    /usr/bin/env env -i \
                /usr/bin/cvs -f --allow-root=/CVS pserver
		

Cette ligne indique au daemon inetd d'écouter sur le port pserver et le lancer la commande /usr/bin/env en tant que root quand une requête est faite sur ce port. Le fait de lancer cette commande avec des droit n'administration n'est pas sécurisée, mais pour l'instant c'est amplement suffisant.

Le paramètre --allow-root=/CVS indique que le repository est /CVS (attention, ce chemin doit être en absolu). Si plusieurs repositories sont présents sur votre machine, if suffit de rajouter autant de paramètres --allow-root que nécessaire.

Après toutes ces modifications, il faut relancer le daemon inetd

        # kill -HUP inetd
		
Il existe une autre version d'inetd: xinetd. La configuration en est légèrement différente. Dans le fichier /etx/xinetd.d/pserver:
        service cvspserver
        {
                socket_type  = stream
                protocol  = tcp
                wait   = no
                user   = root
                server   = /usr/bin/cvs
                server_args  = -f --allow-root=/CVS pserver
                disable   = no
        }
		
Pour relancer xinetd:
        # kill -HUP xinetd
		

4. Utilisation basique de CVS

CVS étant un outil très complet, il vaut bien commencer par bien maîtriser les bases de son utilisation avant de se lancer dans l'administration CVS. Dans cet exemple, le répertoire de travail est ~/work, le serveur CVS est cvs.domain.org et le shell utilisé est le bash (le principe reste le même, cependant quelques commandes système pourront changer).

4.1 Connexion au serveur

Avant de se connecter au serveur, il faut le déclarer à l'aide de la variable d'environnement $CVSROOT.

Connexion locale

        $ export CVSROOT=/CVS
		

Ici, le seul paramètre fournit à CVS est le répertoire (donné en absolue) dans lequel se trouve le repository.

Connexion réseau

        $ export CVSROOT=:pserver:user@cvs.domain.com:/CVS
		

Cette première ligne est plein de renseignements importants:

Lors d'une connexion réseau, il faut se connecter à un serveur. Pour cela, il faut utiliser la commande login de CVS:

        $ cvs login
		

Un mot de passe est alors demandé à l'utilisateur, il suffit de le taper. Si aucun message n'apparaît au prompt, c'est que tout c'est bien passé, vous êtes connecté au serveur.

4.2 Importation du répertoire de travail dans le repository

Le répertoire local de travail étant définit (~/work), il faut importer les fichiers dans le repository au moins une fois pour que cela fonctionne. La syntaxe basique (utilisée dans 99% des cas) pour importer un module dans le repository est la suivante:

        $ cvs import repository vendor-tag release-tags
		

Le plus important là dedans, c'est le paramètre repository. C'est lui qui va créer un nouveau module sur le serveur CVS. vendor-tag et release-tag sont des informations obligatoire mais pas très importantes. Ces paramètres sont tels qu'il apparaissent dans la documentation officielle de CVS, et sont (je pense) très déroutants au départ. De manière plus claire, les paramètres sont:

Une autre option (facultative) est intéressante, il s'agit de -m qui permet de donner un bref descriptif des fichiers importés.

Quelle est la différence entre projet et module?

En gros, un repository contient un (ou plusieurs) projet. Un projet contient un (ou plusieurs) module. Un module contient un (ou plusieurs) sous-module etc.

        CVSROOT
        |
        |------ projet alpha
        |       |
        |       |------ module machin
        |       |       |
        |       |       \------ sous-module machin-truc
        |       |
        |       \------ module bidule
        |
        \----- projet beta
		

Le schéma ci-dessus présente l'organisation des projets et des (sous-)modules dans le repository CVSROOT.

Finalement pour importer un nouveau projet dans le repository la commande sera la suivante:

        $ cvs import -m "Premier import du projet ALPHA" alpha Gilles_Baetz initial
		

Un projet alpha avec le label initial développé par Gilles_Baetz sera importé dans le repository. Il est important de noté que les paramètres vendor-tag et release-tag doivent commencer par une lettre et ne peuvent contenir que des caractères valides pour les noms de variables en programmation classique.

4.3 Synchronisation du repository avec le répertoire de travail

Lors d'un travail en groupe, il est important que chacun travaille avec la même version des fichiers afin d'assurer une bonne compatibilité des modifications. Pour cela il est nécessaire de synchoninser les données personnelles aux données communes avant de commencer à travailler. Après la connexion au serveur CVS, il faut donc lancer un checkout du repository à l'aide de la commande checkout (ou co) de CVS:

        $ cvs checkout module
		

ou de manière plus compacte:

        $ cvs co module
		

À la fin de l'opération, un sous-répertoire module est crée dans le répertoire courant. Ce sous-répertoire contient tous les fichiers et sous-modules du module module ainsi qu'un autre répertoire (à ne pas modifier), CVS qui contient les informations relatives au serveur CVS.

Note: Sur une connexion lente (genre RTC) ou pour éviter une surcharge réseau si le module est de taille importante, l'option -z3 permet de compresser les fichiers lors du transfert.

4.4 Validation d'une modification

Après avoir fait une modification d'un fichier dans l'arborescence locale, il faut la valider dans le repository. La commande commit (ou ci) se charge de cette tâche. Comme pour l'import d'un projet dans le repository, cette commande prend en argument facultatif un descriptif des modifications apportées. Si ce paramètre (-m) n'est pas passé en ligne de commande, l'éditeur par défaut de CVS (variable d'état $CVSEDITOR) est lancé et un commentaire doit être ajouté. La syntaxe de la commande commit est la suivante:

        $ cvs commit -m "commentaire de modification" fichier1 module_alpha
		

Dans ce cas, fichier1 et module_alpha seront importés dans le repository. Si aucun fichier n'est précisé, CVS se chargera de détecter automatiquement quels fichiers seront à importer. Si une erreur de conflit survient, c'est que quelqu'un a validé une modification depuis le dernier checkout. Dans ce cas la copie locale n'est plus synchronisée avec le repository. Il faut alors effectuer une mise à jour du fichier avec la commande update:

        $ cvs update par_ici/par_la/c_ici.sgml
		

CVS se charge alors de fusionner la copie locale et l'original du repository. Si les modifications apportées au fichier sont trop importantes ou trop complexes, il faudra régler le problème manuellement et relancer le commit.

Note: la commande commit est très importante, c'est elle qui sera à appeler pour valider chaque modification dans l'arborescence locale, mais également pour confirmer l'ajout et la suppression de fichiers dans le repository.

4.5 Ajouter un fichier ou d'un répertoire

Lors du développement d'un projet, pour plusieurs raisons diverses et variée, un fichier doit être ajouté (ou supprimé - voir section suivante). La commande est très simple:

        $ cvs add -m "commentaire d'ajout" fichier module
		
Le fichier fichier sera ajouté dans le repository ainsi que le répertoire module. Afin de rendre ces modifications permanentes, il faut lancer un commit.

Dans le cas où un fichier est de type binaire (CVS ne gère que les fichiers textes), il faut l'indiquer à la commande add:

        $ cvs add -m "commentaire d'ajout" -kb fichier_binaire
		

4.6 Suppression d'un fichier ou d'un répertoire

Avant de supprimer un fichier dans le repository, il faut d'abord le supprimer dans l'arborescence locale. Seulement ensuite la commande remove de CVS peut être invoquée, toujours suivie d'un commit:

        $ rm fichier
        $ cvs remove fichier
		
Pour supprimer un répertoire, il faut d'abord supprimer tout ses composants. J'ai tenté la commande remove sur un répertoire du repository sans succès, j'ai effectué les mêmes opération que préconisent Alain Lesné et Olivier Berger dans leur manuel d'introduction à CVS. Si quelqu'un a la solution merci de me le faire savoir par mail.

4.7 Renommer un fichier ou un répertoire

Il n'existe pas de commande pour ce genre d'opération. En fait il s'agit d'une succession de remove, add et de commit.

        $ mv foo bar
        $ cvs remove foo
        $ cvs add bar
        $ cvs -m "foo renomme en bar" ci
		

Pour ce qui est des répertoire, c'est comme pour la suppression des fichiers à la section précédente.

5. CVS avancé

Dans cette partie, les commandes de gestion de version seront abordées. Ces commandes permettent notamment de récupérer des erreurs fatales dues aux modifications d'un fichier.

5.1 Historique des modifications

Au bout de quelques commit faits par plusieurs personnes différentes, il devient vite fastidieux de mémoriser qui à fait quoi. La commande log permet d'afficher un historique des modification:

        $ cvs log fichier
		
Cette commande peut être combinée avec une date ou un intervalle temporel:
        $ cvs log -d "d" fichier
        $ cvs log -d ">d" fichier
        $ cvs log -d "<d" fichier
        $ cvs log -d "d1<d2" fichier
		
Ces instruction donne l'historique respectivement de: Le format des dates est:

5.2 Différence de fichiers

CVS permet de faire un diff entre les fichier pour voir le modifications qui lui ont été apportées. Il existe plusieurs types de diff:

La commande diff de CVS permet de faire tout cela, moyennant quelques options. Voici donc la commandes permettant de visualiser les changements dans un fichier:
        $ cvs diff foo
        $ cvs diff -r 1.2 foo
        $ cvs diff -r 1.2 -r 1.3 foo
		

5.3 Revenir a une version antérieure

Si pour une raison ou pour une autre, il faut revenir à une ancienne version d'un fichier, cela est possible à l'aide de la commande update:

        $ cvs update -A fichier
        $ rm fichier
        $ cvs update -p -r 1.9 fichier > fichier
		
Ensuite un commit doit être effectué pour la validation de retour à une version précédente.

5.4 Annotations

Les annotations permettent de visualiser un fichier de manière annotée. Cela permet de voir rapidement qui à fait quoi et où il l'a fait. La commande annotate donne donc un historique des modifications d'un fichier.

        $ cvs annotate bar
		

5.5 État d'un fichier

Lors d'un développement, si plusieurs fichiers locaux sont modifiés, la commande status renseigne sur l'état du fichier. Elle prévient l'utilisateur si un commit est nécessaire ou si le fichier doit être fusionner avec la copie locale etc.

        $ cvs status foobar
		

6. Lectures

Voici quelques trucs intéressants: