Futur Mac

Utiliser un serveur CVS

Un serveur CVS est un outil permettant des gérer la travail à plusieurs sur un même projet ainsi que de gérer plusieurs versions d'un même projet. Parmit ses concurrents, on trouve les serveurs Perforce et les serveurs Arch.

Ce tutorial explique le fonctionnement de la commande cvs. Il existe cependant des interfaces graphiques permettant d'en simplifier l'utilisation, mais ce tutorial reste entièrement valide dans la description de termes techniques ("checkout", "commit"?) et de ses principes de fonctionnement. Pour adapter ce tutorial à ces utilitaires, il suffirait simplement de remplacer les exemples de code par des captures d'écran, avec un peu d'abstraction on peut imaginer ces captures à partir des lignes de commandes proposées.

Le CVS ne sait fonctionner uniquement sur des fichiers texte. Il est toutefois capable de manipuler des fichiers binaires, mais est incapable d'effectuer bon nombre d'opération sur ces fichiers.

Fonctionnalités principales

Un serveur CVS permet :

Utilisation d'un serveur CVS

Le principe général d'utilisation d'un serveur CVS est de récupérer la version courante du projet, d'effectuer ses modifications puis de réenvoyer au serveur les fichiers modifiés.

Récupération initiale d'un projet (checkout)

Cette récupération s'effectue à l'aide de la commande :

shell% cvs -d «repository» checkout «projet»

Le projet est aussi courament appelé "module". Cette commande créer un nouveau dossier ayant le même nom que le projet contenant les fichiers de ce projet.

Le "repository" peut aussi être spécifier à l'aide de la variable d'environement CVSROOT. Le repository est une chaine de caractère qui donne toutes les informations nécessaires pour accéder au serveur (méthode utilisée, nom du serveur, nom d'utilisateur, chemin d'accès des fichiers CVS). Voici les formats utilisés selon les méthodes utilisé pour accéder au serveur :

Souvent, les serveurs de type "pserver" permettent un accès annonyme avec uniquement un droit de lecture sur les fichiers.

Mise à jour de sa version locale (update)

Avant de travailler sur sa version locale d'un projet, il faut commencer par récupérer toutes les modifications qui ont été effectués par les autres développeurs. Une simple commande permet de le faire (à exécuter à la racine du projet) :

shell% cvs update -d

L'argument -d permet de demander à la commande cvs de tenir compte des dossiers qui ont été créer par d'autres développeurs depuis la dernière mise à jour des fichiers locaux. Si l'on ne met pas ce paramètres, les fichiers contenus dans ces nouveaux dossiers ne seront pas récupérés.

La commande cvs update affiche l'ensemble des opérations effectuées sur les fichiers et leur status à l'aide d'un code de lettres :

Soumettre ses modifications au serveur (commit)

Une fois les modifications effectuées, il faut les envoyer sur le serveur afin d'en faire profiter les autres personnes travaillant sur le projet. Cette opéraition est appelée "commit" et s'effectue avec la commande (à exécuter à la racine du projet) :

shell% cvs commit

Avant d'effectuer un cvs commit, il peut être utile de faire une mise à jour avec un cvs update afin de tenir compte des modifications effectuées entre temps par d'autre utilisateurs. Si cette mise à jour n'est pas faite, le commit ne sera pas effectué et un message d'erreur s'affichera. S'il y a des conflits lors de cette mise à jour, les conflits doivent être traités avant d'effectuer le commit.

Lors du commit, la commande cvs va demander de donner un petit texte d'écrivant les modifications effectuées sur les fichiers. Par défaut, cette description est demander à l'aide de la commande vi : taper "i" pour passer en mode insertion, taper son texte puis ESC et ":wq" pour valider.

Ajout et suppression de fichiers (add et remove)

Pour ajouter un fichier sur le serveur, créer le fichier sur la copie locale du projet, puis exécuter la commande :

shell% cvs add «fichier»

Après cette commande, le fichier n'est que marqué comme devant être ajouter (il apparaîtera alors avec le status 'A' et non '?' lors des commandes cvs update). Pour envoyer effectivement les nouveaux fichiers vers le serveur, il faut effectuer un commit.

Le principe est exactement le même pour la suppression des fichiers. Il faut d'abord supprimer le fichier en local puis exécuter la commande :

shell% cvs remove «fichier»

La suppression effective sur le serveur n'aura lieu que lors du prochain commit.

Il n'est pas possible de déplacer un fichier avec CVS (c'est une de ses limites les plus génantes). La seule solution consiste à déplacer le fichier localement puis d'effectuer un cvs delete suivit d'un cvs delete.

Administration d'un serveur cvs

L'administration d'un serveur CVS se fait uniquement avec la commande cvs, jamais en allant modifié les fichiers du serveur CVS. D'ailleurs la seule opération à effectuer sur le serveur est de créer le dossier qui servira de repository CVS lors de la création d'un serveur CVS et à la rigueure de modifier les droits sur les dossiers du serveur CVS pour limiter l'accès aux projets à certains développeurs uniquement.

Création d'un serveur cvs

Tout d'abord, il faut créer, sur le serveur, le dossier qui servira de repository (généralement /cvs, /home/cvs ou /var/cvsroot) en lui donnant les permissions nécessaires pour permettre l'utilisation du serveur par le groupe cvs. Ensuite il ne reste plus qu'à initialiser le serveur avec commande :

shell% cvs -d «repository» init

C'est tout ! Le serveur CVS est maintenant opérationnel.

Import d'un nouveau projet, ajout d'un projet

Imaginons que l'on dispose d'un projet déjà existant dont tous les fichiers sont stocké dansun dossier /home/moi/mon_projet et que l'on souhaite rajouter ce projet sur le serveur CVS. Il va falloir effectuer ce que l'on appelle une importation de projet à l'aide des commandes suivantes :

shell% cd /home/moi/mon_projet
shell% cvs -d «repository» import «nom du projet» «tag provenance» «tag version»

Le «nom du projet» est le nom qui servira à effectuer des cvs checkout, le «tag provenance» est un nom qui indique la provenance du code importer et le «tag version» est un nom qui indique la version du code importé. Si l'on dispose des sources de différentes version d'un projet, il est possible d'effectuer plusieurs import avec des «tag version» différents.

shell% cd /cdrom/driver_carte_X345_1/
shell% cvs -d :ext:moi@serveurcvs:/home/cvs import driver_X345 sauvegarde_CD v1
shell% cd /cdrom/driver_carte_X345_2/
shell% cvs -d :ext:moi@serveurcvs:/home/cvs import driver_X345 sauvegarde_CD v2
...

Pour créer un nouveau projet sans aucun fichiers, il suffit de faire la même chose, mais en étant dans un dossier ne contenant aucun fichiers :

shell% mkdir projet_test; cd projet_test;
shell% cvs -d /home/cvs import test aucun version_0

Modification des paramètres du serveur

Dans chaque repository CVS, il existe un module appelé CVSROOT qui contient les fichiers de configuration du serveur. Ce module est lors de l'initialisation du serveur CVS. Il fonctionne exactement comme tous les autres modules, récupération avec la commande cvs checkout, modification des fichiers en local puis envoie des modifications avec un cvs commit, précédé d'un cvs update bien sûr.

Je ne détaillerais pas le rôle de chacun des fichiers contenu dans ce module, il suffit de lire les commentaires contenus dans ces fichiers pour savoir à quoi ils servent. Je ferais cependant une petite remarque concernant le fichier "checkoutlist" : si vous souhaitais rajouter un fichier dans le module CVSROOT, il faut absolument rajouter son nom dans ce fichier "checkoutlist".

Mise en place d'un serveur anonyme ou avec accès par mot de passe (pserver)

Pour l'instant votre serveur CVS n'est accessible qu'en local ou via un serveur rsh ou ssh. Si vous ne souhaitez pas ouvrir de compte à tous les développeurs sur la machine hébergeant le serveur CVS ou si vous souhaitez mettre en place un accès annonyme en lecture, il peut être utile d'installer un "pserveur".

La manière la plus simple d'installer un tel serveur est d'utiliser inetd (ou xinetd). Dans ce cas, il suffit de rajouter la ligne suivante dans le fichier de configuration de inetd (/etc/inetd.conf) :

cvspserver	stream	tcp	nowait	root	/usr/libexec/tcpd	/usr/bin/cvs --allow-root=«repository» pserver

Ou pour xinetd, créer un fichier /etc/xinetd.d/cvspserver contenant :

service cvspserver
{
    disable = no
    socket_type = stream
    wait = no
    user = root
    server = /usr/bin/cvs
    server_args = --allow-root=«repository» pserver
    groups = yes
    flags = REUSE
}

Vérifiez aussi que le fichier /etc/services contient bien une entrée pour le service cvspserver associée au port TCP 2401.

Le serveur est alors fonctionnel, mais il manque encore une description des utilisateurs et leur mots de passe : le serveur psersver n'utilise pas le fichier /etc/passwd mais un fichier propre à lui, ce qui permet de créer des utilisateurs indépendant des utilisateurs système. La liste des utilisateurs est définie dans le fichier CVSROOT/passwd sous la forme :

«login»:«mot de passe crypté»:«utilisateur système correspondant»

Le mot de passe est crypter comme ceux de /etc/passwd. On peut utiliser les fonctions htpasswd -n ou openssl passwd pour calculer le hash correspondant à un mot de passe. Le troisième paramètre est l'utilisateur système utilisé pour définir les droits d'accès aux fichiers du repository.

Pour permettre un accès anononyme, il faut créer un fichier CVSROOT/readers contenant les noms d'utilisateur ("anonymous" ou "anoncvs" en général) pouvant accéder au repository sans mot de passe avec des droits de lecture uniquement.

Utilisation avancée

Paramètres par défaut des commandes cvs

Il est possible de définir des paramètres par défaut pour les commandes cvs. Pour cela, il faut créer un fichier .cvsrc dans son home contenant sur chaque ligne le nom de la commande cvs suivit des paramètres par défaut de cette commande. Une configuration assez courrante est :

checkout -P
update -P -d
diff -u -d -b -w
rdiff -u

Ainsi, les prochaines exécutions de la commande cvs update correspondera à une commande cvs update -P -d.

Il est aussi possible possible de définir un repository par défaut qui sera utilisé si l'option -d est manquante. Cette valeur par défaut est stockée dans la variable d'environement CVSROOT.

Récupération des logs de commit et d'autre information d'un fichier

Pour avoir des informations sur un fichier, il faut utiliser la commande cvs «commande» suivit du du chemin relatif du fichier dont on souhaite avoir les informations. «commande» peut être status pour avoir les numéros de version du fichier, log pour avoir l'historique des commits et leurs commentaires, annotate pour avoir des notes indiquant pour chaque ligne du fichier la date à laquelle elle à été écrite et qui l'a écrite.

Navigation dans le temps, utilisation des tags

Le serveur CVS enregistre toutes les modifications de manière incrémentielle, il est donc capable de restituer l'état du projet à n'importe quelle date. Pour cela, certaines commandes, comme les commandes checkout et update, permettent d'utiliser le paramètre -D «date» pour spécifier la date de la version que l'on souhaite récupérer. «date» peut être une date absolue ou relative : 2004-04-19, "19 Apr 2004 22:30:30 GMT", 19 Apr, 3 days ago, 1 hour ago.

shell% cvs -d «repository» checkout -D "1 day ago" mon_projet

Il n'est aisé, après que plusieurs mois ce soient écoulés, de savoir quelle date mettre pour récupérer une version donnée. Pour cela, CVS permet de mettre des tags, une chaîne de caractères quelconque, sur une version donnée à l'aide de la commande :

shell% cvs tag -D «date» «nom du tag»

Ainsi, la version à la date «date» à maintenant un nom. Il est possible de ne pas mettre de paramètre -D, dans ce cas, le tag est appliqué à la version des fichiers locaux. Par défaut le tag est appliqué à tous les fichiers contenu dans le répertoire courant, mais on peut spécifier des fichiers après le nom du tag dans la commande.

Pour accéder à une version spécifier par son tag à la place d'une date pour les commandes cvs update ou cvs checkout, il suffit de remplacer le paramètre -D «date» par -t «tag».

shell% cvs -d «repository» checkout -t version_1_2 mon_projet

Vous remarquerez qu'il n'est pas possible d'effectuer un commit depuis une version récupéré avec l'une des options -D ou -t.

Branches

Par défaut, il n'existe qu'une seule branche, la branche principale. Pour créer une deuxième branche il faut tout d'abord choisir le point de la branche principale d'où partira la seconde branche. Pour cela il suffit de mettre un tag à ce point, avec l'option -b signifiant que l'on veux créer une nouvelle branche à partir de ce tag.

shell% cvs tag -b -D «date» «nom de la branche»
shell% cvs update -t «nom de la branche»

Il est maintenant possible de faire des modifications sur la copie locale des fichiers, les commits auront lieux sur une nouvelle branche indépendante de la branche principale.

Références