Accueil - Informatique - Programmation - Outils

CVS Guide de l’utilisateur

Publié le mardi 7 septembre 2004.


CVS (Concurrent Versions System) est un outil d’aide au développement de logiciels. Très présent dans le monde des programmeurs Open Source, il permet une gestion efficace et riche des différentes versions des documents constituant un projet (programme, site Web, documentation, etc).

Mis à jour 8 mars 2007

Utilisation de CVS coté client

I Préliminaires :

La forme générale d’une commande CVS est la suivante :

cvs [options générales] <sous commande> [options] [arguments]

Les options générales les plus courantes sont :

- Remplace la variable d’environnement $CVSROOT.

cvs -d <cvs_root> <commande>

- N’effectue aucune action qui changerait l’état du répertoire local.

cvs -n <commande>

- Utilise le niveau de compression compris entre 1 et 9 (-z 3 par ex).

cvs -z <niveau> <commande>

Le fichier ~/.cvsrc permet de spécifier des arguments communs aux différentes commandes comme :

diff -c
commint -n
status -v

II Syntaxe générale d’une commande :

cvs -d :pserver:user@cvs.mpl.ird.fr:/projet login
       (1)     (2)      (3)          (4)      
        |       |        |            |
        |       |        |            +- Répertoire du
        |       |        |    SERVEUR contenant les sources
        |       |        |              (racine)
        |       |        |    
        |       |        |  
        |       |        +-------- adresse du SERVEUR CVS
        |       |
        |       +------ Votre login à vous sur le SERVEUR
        |
        +----- le type d'authentification

Pour nos projets, nous utiliserons l’accès en mode pserver sur le port 2401.
Une fois la base CVS installée dans le référentiel du serveur (repository), se placer dans sa copie de travail (repertoire local sur un espace disque vous appartenant).
On utilise généralement /cvs.
Mettre à jour la copie de travail en utilisant l’option -d ou après avoir déclarée la variable d’environnement $CVSROOT par :

$> export CVSROOT=:pserver:jgrelet@cvs.mpl.ird.fr:/projet
$> cvs login
$> cvs checkout thermo

La commande login va créer un fichier /.cvspass qui contiendra une entrée pour cette connexion avec le mot de passe.
Cette entrée restera valide tant que la commande logout n’aura pas été effectuée.

L’utilisateur jgrelet devra être enregistré dans le référentiel CVS avec un mot de passe. Cela lui permettra de soumettre (droit en écriture) des modifications.
Pour un utilisateur “lambda”, il faudra utiliser le mode anonymous (login : anoncvs, password : anoncvs).

La commande checkout (co) va créer une arborescence complète du projet.
Dans le cas du projet thermo ou ROMS-Agrif, il suffira ensuite de le compiler avec la commande make (propre au projet thermo) en suivant les instructions du fichier README ou INSTALL.
Il faut bien avoir à l’esprit que CVS travail toujours en relatif par rapport au répertoire courant.

Par la suite, avant chaque modifications que vous allez effectuer sur votre copie de travail, il est conseillé de mettre a jour votre répertoire local a partir du référentiel avec la commande update :

$> cd ~/cvs ; cvs update -dP thermo
ou
$> cd ~/cvs/thermo ; cvs update -dP

Les options -d et -P permettent respectivement de rajouter dans votre copie local les répertoires qui auront été ajouter dans le référentiel, et -P de supprimer localement les répertoires qui auront été supprimés du référentiel.

Les commandes cvs sans arguments agissent récursivement sur le contenu du module (répertoire).
C’est équivalent à l’option -R.

Faire ensuite vos propres modifications puis soumettez les avec la commande commit.

Syntaxe générale de commit :

$> cvs commit -m &#8220;mes commentaires et descriptifs sur les modifs&#8221; <fichiers>

Si vous ne spécifiez pas l’option -m dans votre commande cvs commit, CVS lance l’éditeur de texte par défaut (définit avec la variable d’environnement $EDITOR et VI par défaut) dans lequel vous devez saisir votre commentaire.
Commentaire qui apparaîtra lors de l’utilisation de la commande cvs log.

Important : La commande update met à jour votre copie de travail à partir de la branche principale du référentiel.

Utiliser l’option -n (cvs -n update) pour visualiser qu’elles seront les actions qui seront réalisées sans modifier votre copie de travail.

Si vous avez rajouté un fichier dans le projet, ajouter manuellement ce fichier dans le référentiel avec la commande add puis soumettre la modification dans le référentiel avec commit.
On peut ajouter plusieurs fichier, puis faire un commit général.

$> cvs add -m "mes commentaires" <fichier>
$> cvs commit <fichier>

Idem pour supprimer un fichier avec la commande remove.

III Utilisation en mode anonymous :

Le mode anonymous permet simplement à n’importe quel utilisateur de récupérer une copie du référentiel, ceci en lecture uniquement :

Vous pouvez recuperer le projet sous cvs comme suit sous anonymous avec le login anoncvs et password anoncvs :

brest> cvs -d:pserver:anoncvs@cvs.mpl.ird.fr:/projet login
Logging in to :pserver:anoncvs@cvs.mpl.ird.fr:/projet
CVS password: anoncvs
brest> cvs -d:pserver:anoncvs@cvs.mpl.ird.fr:/projet co thermo
cvs server: Updating thermo
U thermo/BUGS
U thermo/CHANGES
U thermo/INSTALL
U thermo/Makefile
U thermo/README
U thermo/README-CVS
U thermo/TODO
U thermo/Thermo.doc
cvs server: Updating thermo/prj
cvs server: Updating thermo/prj/mkascii
U thermo/prj/mkascii/Mkascii.manifest
....

IV Création d’un module :

Cette commande est utilisée pour transférer un projet dans son état actuel d’avancement.

Ne pas oublier de se placer dans le répertoire racine du projet avant d’utiliser la commande cvs import.

La syntaxe est la suivante :

cvs import -m "description" module vendor_tag release_tag

Exemple :

$> cd rep_du projet
$> cvs import -m "mes commentaires" rep_du projet mon_tag ma_version

Les informations vendor_tag et release_tag ne sont pas d’une importance primodiale pour la suite du projet mais sont obligatoires.

Lorsque le module aura été importé sur le référentiel CVS, il faudra en récuperer une copie locale avec la commande cvs ceckout module.

V Renommer un fichier :

Pas de commande spécifique pour cela, il faut réaliser les opérations suivantes :

$> mv <old-file> <new-file>
$> cvs remove <old-file>
$> cvs add <new-file>
$> cvs commit -m <new-file>

VI Ajout d’une arborescence (répertoire) :

Utiliser la commande :

$> cvs add <rep>

Le répertoire est créé immédiatement dans la base sans qu’il y ait besoin d’utiliser la sous commande commit.
Si le répertoire contient des fichiers, il faudra les ajouter par le biais d’une ou plusieurs commandes cvs add et cvs commit.

Une autre solution est d’utiliser la commande cvs import pour ajouter un nouveau module ou une nouvelle arborescence comme décrit au chapitre IV.

Cette sous commande doit être utilisée en dehors de la copie de travail. Sinon, renommer le répertoire après la commande commit, et faire un cvs co <module> depuis la racine du projet.
Ne pas oublier de se placer dans le répertoire que l’on veut ajouter au module avant d’utiliser la commande cvs import.

$> cd thermo/rep
$> cvs import -m "mes commentaires" thermo/rep Init version
$> mv thermo/rep thermo/rep.old
$> cd ../..
$> cvs co thermo/rep
$> cd thermo/rep  (ls et si contenu correct, faire rm -r rep.old)

Dans tous les cas, pour que ce nouveau répertoire apparaisse dans la copie locale du client, il faudra impérativement utiliser l’option -d de la commande update :

$> cvs update -d

VII Suppression d’un répertoire :

Supprimer localement les fichiers du répertoire puis utiliser les commandes remove et commit pour mettre à jour le référentiel.
En aucun cas le répertoire ne peut être supprimé du référentiel.
Utiliser la commande update -P pour supprimer le répertoire vide de votre copie de travail.

$> cvs remove <fichier> <fichier>
$> cvs commit
$> cvs update -P

VIII Historique :

$> cvs log <file>
$> cvs status -v <file>
$> cvs status -v -r 1.3 <file>
$> cvs status -v -r V0_30-1
$> cvs diff -r 1.2 -r 1.3

IX Les tags (contraintes) :

Les tags (contraintes) permettent de figer un module, un ou plusieurs fichiers.
Il faut avant tout bien comprendre le sens des révisions avec CVS. A chaque fois que l’on va modifier un fichier dans le référentiel, son numéro de révision va être incrémenté (1.1, 1.2, etc.).
Pour figer un module dont les fichiers ont des révisions successives différentes, on va utiliser la commande tag (label symbolique) ou rtag (label de version) pour contraindre (ou figer) cette version.

Les contraintes se font sur une date (-D), sur un nom symbolique ou un numéro de révision (-r).

La sous-commande tag permet d’appliquer un label symbolique de version sur le ou les fichiers de la copie de travail.

La sous-commande rtag permet d’appliquer un label symbolique de version sur un ou plusieurs modules. Utilisée également pour la création des branches.

Dans la branche courante :

$> cvs tag <nom tag>
$> cvs tag -c <nom tag>

L’option -c permet de vérifier que les fichiers de travail ne sont pas modifiés. Si c’est le cas, l’exécution de la commande est abandonnée.

Dans une branche :

$> cvs rtag -r <branche> <nom tag>

Supprimer une contrainte :

$> cvs tag -d <nom tag>

Afin de ne pas confondre avec les numéro de révisions, on ne peut pas utiliser de point (.) pour les noms symboliques.

La mise à jour de la copie de travail à partir d’une contrainte se fait comme suit :

$> cvs update -r CONTRAINTE

La contrainte comme on va le voir ci-dessous, peut être appliquée sur une révision ou sur une branche. Voir le résultat « Existing Tags » de la commande update).
Dans tous les cas, sauf pour update -A, les fichiers de la copie de travail mis à jour avec l’option -r vont posséder un tag collant (sticky tag) qui empêchera de faire des modifications (commit) dans la branche principale (trunk).

Le mécanisme pour soumettre des modifications dans une branche est expliqué dans le paragraphe “soumettre dans une branche”.

X Les branches :

CVS permet de gérer plusieurs branches de développement. Pour créer une branche à partir d’une version contraintes dans le référentiel utiliser l’option -b :

$> cvs rtag -b -r CONTRAINTE CONTRAINTE-BRANCHE <fichier>

Pour récupérer un module depuis une branche :

$> cvs checkout -r CONTRAINTE-BRANCHE <module>

Il est possible de revenir à tout instant à la branche principale par le biais de la commande update -A :

$> cvs update -A

Pour fusionner, c’est a dire, intégrer les modifications d’une branche au sein de la branche principale (trunk), utiliser l’option update -j :

$> cvs update -j CONTRAINTE-BRANCHE

XI Soumettre dans une branche :

Créer la branche depuis la racine de CVS avec rtag (voir CVS Guide) :

$> cvs rtag -b -r CONTRAINTE CONTRAINTE-BRANCHE <module>
$> cvs co -r CONTRAINTE-BRANCHE <module>
$> cd module
[faire ses modifs]
$ cvs commit

Créer la branche après édition, au cas ou vous avez, emporté dans votre élan, fait des modifications expérimentales, que vous ne voulez pas soumettre dans le référentiel principal, au risque de perturber le travail de vos collègues :

[sources modifiés]
$> cvs tag -b CONTRAINTE-BRANCHE
$> cvs update -r CONTRAINTE-BRANCHE
$> cvs commit
$> cvs status -v <file>

Pour visualiser les modifications sur le référentiel, on doit bien se trouver sur une branche avec le sticky tag marqué de la contrainte CONTRAINTE-BRANCHE.

Une fois le code expérimental mis au point et validé, vous pourrez fusionner le code avec update -j.

XII Les préfix des messages CVS :

Lors des opérations sur le répertoire de travail local avec la commande update, CVS affiche des messages ou les noms des fichiers sont précédés d’une lettre :

U Updated vous venez de récupérer la dernière version du fichier
P Patched vous venez de mettre à jour le fichier de votre copie de travail
M Modified vous avez modifié le fichier de votre copie de travail par rapport au référentiel
C Conflict un commit à été fait sur le fichier par une autre personne, il faut éditer le fichier à la main pour résoudre le conflit
T Tagged vous venez de placer un tag sur le fichier
 ? Unknown le fichier n’appartient pas au référentiel

Lorsque qu’un fichier est marqué C, il faut l’éditer à la main pour résoudre le conflit :

<<<<<<< thermo.java
import thermo.util.*
=======
import thermo.util.Constant
>>>>>>> 1.15

Vous devrez alors choisir (ou extraire de code correcte) entre la version du référentiel marquée entre <<<<<< et ===== et votre version entre ===== et >>>>>>.

XIII Retour en arrière :

Lors du développement, vous estimez qu’une version antérieure est préférable à la dernière version de la base, il est possible de replacer cette version antérieure à la suite de la dernière version disponible.

Une erreur fréquente consiste à rappeler la version souhaité avec update -r TAGS.
Lorsque l’on a vérifié que cette révision donnait satisfaction, il est ensuite impossible d’effectuer un commit car le fichier possède un sticky tag.
Il faut pour cela au préalable le placer dans la copie locale avec l’option -p, qui extrait le fichier sur la sortie standard, sans mettre à jour les informations de version. Une fois les vérifications d’usage réalisées, on peut effectuer un commit :

$> cvs update -p -r 1.7 fichier > fichier
$> cvs commit -m &#8220;blab la&#8221; fichier

Travail par erreur hors de la branche :

Une autre erreur courante, lorsque l’on travail sur une branche, est de vouloir importer un fichier depuis la branche principale (HEAD ou trunk) avec la commande update -A.

Comme précédemment, le fichier aura un sticky tag et toute les mises à jour se feront dans la branche principale, et non plus dans la branche sur laquelle on travail.
Et pourtant, en local, ça compile (attention à bien vérifier les numéro de révision lors du commit).
La bonne méthode consiste à faire une jointure avec le fichier de la branche principale depuis la branche de travail :

$> cvs update -r BRANCHE         # se placer dans la branche
$> cvs update -j HEAD fichier
[hacking...]        
$> cvs commit -m &#8220;blab la&#8221; fichier

Exporter le code source d’un module

Dans un projet, la majorité des utilisateurs ne sont interessés que par l’utilisation du code source pour déployer localement l’application. Pour cela il peut être interessant de proposer une archive expurgée des répertoires d’administration de cvs que l’on mettra à disposition sur le web sous une forme compressée.
Couramment, 2 solutions se présentent à l’utilisateur :
- Exporter une version (1.0, 1.1,...) à l’aide de l’option -r
- Exporter la version "courante" à l’aide de l’option -D now

Exemple, pour exporter le code source via la commande export :

$ cvs export -r <tag> <repertoire dest> <module>
$ tar zcvf <mon archive> <repertoire dest>
$ cp <mon archive> <a disposition>

XIV Mots clés de substitution :

Pour identifier les différentes révisions des fichiers hors du contexte de travail de CVS, il est possible de placer des mots clefs dans les sources qui seront substitués lors de la soumission dans le référentiels comme $Id$ et $Version$ ou encore $Log$.

/**********************************************************************
* Module principal du programme Thermo.
*
* @version $Id$
**********************************************************************/
devient
/**********************************************************************
* Module principal du programme Thermo.
*
* @version $Id: Thermo.java,v 1.9 2002/03/07 15:52:04 jgrelet Exp $
**********************************************************************/

XV Utilisation et installation coté serveur :

Je vais décrire dans ce paragraphe, uniquement l’installation de cvs en mode pserver avec inetd.

Pour des installations plus sécurisées, on pourra l’installer en chroot sans/avec un tunnel ssh par exemple.

Le principe est quasiment le même sous le distribution Linux récentes sauf pour la configuration d’xinetd qui diffère quelque peu d’inetd.

Compiler le programme à partir des sources. Sous Solaris générer le makefile avec la commande suivante :

$> ./configure -without-gssapi
$ make
# make install

Ajouter la ligne dans /etc/services :

cvspserver        2401/tcp

Ajouter la ligne dans /etc/inetd.conf :

cvspserver      stream  tcp     nowait  root    /usr/local/bin/cvs cvs -f --allow-root=/export/home/cvs/projet pserver

Créer un utilisateur cvsuser sans shell (/bin/false), créer un répertoire sous /export/home/cvs/projet par exemple appartenant à cvsuser (attention aux droits).

Redémarrer inetd

/etc/init.d/inetsvc [start/stop]

Créer le référentiel en local avec cvs init, ce qui à pour effet de créer un répertoire CVSROOT sous /export/home/cvs/projet puis créer un fichier passwd sous CVSROOT avec la commande

htpasswd -bc passwd login password.

On éditera ensuite ce fichier pour rajouter la troisième colonne pour les utilisateurs dûment enregistrés, qui auront le droit de faire des dépôts dans le référentiel avec les droits de cvsuser :

cvsanon::
user1: ygRqX7s!nc:cvsuser
user2: gyRFds45m:cvsuser
user3: J06R56jk90:cvsuser

Attention : Par la suite, ne pas utiliser l’option -c pour ajouter un utilisateur, sous peine d’écraser le fichier passwd.

htpasswd -b passwd login password.

Cette installation en mode pserver n’est pas sécurisée. Pour un serveur en production, il faudra de préférence utiliser un accès par un tunnel ssh et chrooter CVS.
Voir liens utiles en fin d’article.

Il est possible d’administrer à distance le fonctionnement de CVS en récupérant dans sa copie de travail le module CVSROOT par une commande classique :

$> cvs co CVSROOT.
$> cd CVSROOT ;vi cvswrappers

en ajoutant les lignes suivantes :

# For example:
*.gif -k 'b'
*.jpg -k 'b'
*.jpeg -k 'b'
*.jar -k 'b'
*.tgz -k 'b'
*.zip -k 'b'

pour permettre automatiquement un archivage correct des fichiers binaires (images, archives, etc.) :

$> cvs commit -m

XVI Liens utiles :

CVSHome pour récupérer les sources et la documentation officielle et diverse installations.

Une bonne introduction en français, site Idealx.

Une mini HowTo en Français.

Le livre CVS, Précis et concis, O Reilly.

Le site d’entraide des développeurs Français.

CVS sous Eclipse.

Un environnement complet de développement GNU sous Windows 9x/2000 : Cygwin incluant un client CVS.

Subversion : Une alternative à CVS

Présentation PowerPoint

Présentation CVS
Document PowerPoint présentant le principe et les fonctionnalités de CVS.
CVSHOME