Tuto : http://www.siteduzero.com/tutoriel-3-2651-un-gestionnaire-de-version.html ====== 1. Introduction ====== [[http://subversion.tigris.org/| Subversion]] est un sytème de **contrôle de version centralisé**. Il a été conçu comme successeur du vénérable [[http://www.nongnu.org/cvs/| CVS]], comme une solution plus robuste et exensible. Un système de contrôle de version vise plusieurs objectifs : * permettre la **collaboration** entre plusieurs utilisateurs sur un projet (fichiers) commun(s) * permettre la maintenance smultanée de différentes versions d'un même projet * tracer et enregistrer l'historique de toutes les modifications effectuées * consulter les informations historiques, effectuer des comparaisons dans le temps Il existe de nombreux systèmes de contrôles de version comparables, comme notamment //Perforce// (propriétaire). A noter qu'il existe une famille nombreuse de système de contrôle de version dit distribuées, où il n'y a pas de distinction explicite client/server: GIT, Bazaar, Mercurial, Arch, Svk, Monotone, etc. ====== 2. Notions fondamentales ====== ===== Repository ===== Subversion utilisant un modèle centralisé, on peut donc désigner un //serveur// dont le rôle va d'être héberger un //repository// (dépôt). Chaque dépôt est associé avec sa méthode d'accès, ses utilisateurs, ses droits particuliers. On peut créer plusieurs dépôts distincts pour isoler des projets. Un repository contient en particulier les données du projet et toutes ses informations historiques. Avec Subversion, la taille du repository est donc en constante augmentation. Cette augmentation est liée à la quantité de modifications apportées (et leur nature). ===== Serveur ===== Il existe plusieurs types de modèle serveur pour publier un //repository//. Il est en particulier possible de s'en passer quand le client et le serveur sont sur la même machine, Subversion pouvant se contenter d'accès direct aux fichiers. Nous verrons que les autres modèles s'appellent //svnserve//, //ssh// et //WebDAV//. ===== Utilisateurs ===== Bien que la notion d'utilisateur soit facultative (on peut proposer une lecture/écriture pour tout le monde), elle est fondamentale pour le traçage: il est important de savoir qui a effectué quoi, même si le mécanisme d'authentification des utilisateurs n'est pas sécurisé. L'implémentation dépend du modèle serveur utilisé. ===== Check out, Working copy ===== Chaque client peut travailler sur le projet en obtenant une //copie de travail// grâce à une opération dite de //check out//. On peut donc travailler avec Subversion de manière déconnectée, la synchronisation ayant lieu qu'à des moments choisis. Chaque client peut utiliser autant de copie de travail qu'il le souhaite, en particulier il est naturel d'en avoir une par version maintenue d'un même projet (projet-1.1, projet-1.2, etc). ===== Update ===== Un client souhaite régulièrement récupérer les dernières modifications des autres utilisateurs en mettant à jour sa copie de travail, c'est l'opération //update//. Celle-ci peut prendre en compte le fait que vous avez modifié des fichiers en même temps que vos collègues. Traditionnellement, on effectue un //update// juste avant de commencer une séance de travail sur sa copie de travail, afin de minimaliser l'effort de synchronisation au //checkin// en fin de séance. ===== Check in, Commit ===== Lorsqu'on désire publier des modifications effectuées dans sa copie de travail, on effectue un //checkin//. Subversion est un système dit **optimiste**: il considère que le cas où deux personnes ont travaillé simultanément est l'exception, et ne verrouille donc aucune ressource. Si un utilisateur a effectué des modifications en même temps que vous mais les a //commitées// avant vous, vous allez faire face à un //conflit//: il vous suffit de prendre une décision et de l'appliquer. Subversion gère de façon intelligente les conflits: si deux personnes ont touchées à des portions //différentes// d'un même fichier, il peut en général résoudre le problème tout seul. Un conflit est normalement le signe d'un problème de gestion de projet et doit déclencher une résolution sur le plan organisationnel et humain ! ===== Changeset ===== L'ensemble des modifications que vous publiez peut contenir différentes informations: * changement de contenu des fichiers * renommage/déplacement de fichiers, de répertoire * modifications d'attributs (exécution, etc) Subversion rassemble l'ensemble de ces modifications dans une opération appelée //changeset// et vous garantit qu'un //commit// est **atomique**: soit l'ensemble du //changeset// est effectivement enregistré sur le serveur, soit il est totalement ignoré (erreur de transmission, interruption volontaire, conflit, etc). Les //changesets// sont simplement numérotés à partir de 1 et leur série constitue l'historique globale du //repository//. ====== 3. Mise en place ====== ===== Repository ===== Il est très simple de créer un repository, il prendra la forme d'un répertoire contenant un ensemble de fichiers variés. Il existe deux formats de repository, donc **bdb** qui devient obsolète (et ne fonctionne pas sur NFS). Exemple : /tmp/repository$ svnadmin create --fs-type fsfs projet1 ===== Via les fichiers ===== On peut se passer d'un serveur spécifique et utiliser directement les fichiers, y compris via NFS pourvu que le serveur gère correctement le //locking// (courant avec NFSv3). Dans ce cas un client peut obtenir une copie de travail très simplement : $ svn checkout file:///tmp/repository/projet1 $~/work$ cd projet1 $~/work/projet1$ Les droits d'accès sont naturellement gérés par le système de fichiers et peuvent être exploités en tant que tel. Il est très classique de créer un groupe Unix correspondant à un projet et d'autoriser les utilisateurs à participer en les incluant (ou non) dans ce groupe. Côté administratif la solution est triviale : /tmp/repository$ chgrp -R codeurs projet1 ===== Via svnserve ===== Il s'agit du protocol réseau "natif" de Subversion, il peut être utilisé de deux façons: * en lançant explicitement le démon **svnserve** * en gérant le démon **svnserve** via le superdémon //inetd// (classique) Dans ce modèle, l'authentification et l'autorisation suit un modèle très simple, basé sur les informations contenues côté repository dans conf/svnserve.conf: * **anon-access = none** : aucun accès public, authentification requise en lecture **et** écriture * **anon-access = read** : on a un accès en lecture publique, les écritures doivent être authentifiées * **anon-access = write** : on a un accès lecture/écriture publique L'authentification se fait via un fichier de mot de passe contenant des identifiants et des mots de passe en clair (voir l'option **password-db**). Les autorisations sont plus simples car le serveur tourne sous une identité Unix prédéfinie, donc le système de fichiers n'est pas une solution praticable pour moduler les accès. Il est possible de gérer des accès basé sur le chemin (voir **authz-db**). Le client peut alors obtenir en copie de travail avec: ~/work$ svn checkout svn://serveur/projet1 Le port standard de //svnserve// est **TCP/3690**. ===== Via SSH ===== Il s'agit de l'option la plus commune. Elle a l'avantage de combiner l'utilisation native des droits du système de fichier, le transport omniprésent et sécurisé de SSH et ses divers mécanismes d'authentification (notamment par clé publique, évitant la gestion de mot de passe). Si le serveur à un démon SSH opérationnel, le client peut obtenir une copie de travail simplement: ~/work$ svn checkout svn+ssh://serveur/tmp/repository/projet1 On remarque qu'il s'agit tout simplement du tunneling du protocole //svnserve// via SSH (on voit effectivement des processus //svnserve// côté serveur). ====== 4. Utilisation pratique ====== ===== Update ===== Une fois une copie de travail obtenue, Subversion mémorise la méthode d'accès et dans certains cas les informations d'autorisation (//svnserve//). Il suffit donc de se rendre dans sa copie de travail et exécuter des commandes Subversion. La mise à jour est récursive par défaut, et peut se faire dans n'importe quelle partie de l'arborescence du projet (mise à jour partielle): ~/work/projet1$ svn up A dev/dslice/vendor/gems/image_science-1.1.1/README.txt U dev/dslice/config/routes.rb U dev/dslice/config/environment.rb Updated to revision 21442. Très souvent, on désire simplement estimer quelles mises à jour seraient effectuées (pour étudier l'activité sur le repository, vérifier qui travaille sur quoi, etc): ~/work/projet1$ svn status -u Par défaut les fichiers et répertoires que l'on créée ne sont pas pris en charge par Subversion. Il faut explicitement les ajouter au //repository//. La commande //add// est récursive par défaut: ~/work/projet1$ svn add NEWS ~/work/projet1$ svn add lib ===== Commit ===== Pour publier ses modifications, il suffit d'appeler la commande //checkin//. Par défaut celle-ci lance un éditeur pour saisir un message décrivant l'impact des modifications publiées. Si le message est simple on peut le passer en ligne de commande : ~/work/projet1$ svn commit -m "fixed bug #235" On peut estimer à tout moment quelles sont les modifications que l'on a effectuées par rapport à la dernière mise à jour de notre copie de travail : ~/work/projet1$ svn status ~/work/projet1$ svn diff ===== Conflits (update) ===== Les conflits arrivent. Ne jamais oublier qu'ils sont en général la conséquence d'un problème de gestion de projet qui peut parfois se régler en allant voir 2 minutes son collègue. Lors d'une mise à jour, il peut y avoir conflit entre un fichier mis à jour par vos soins et simultanément par un autre utilisateur. Dans ce cas vous verrez apparaître le fichier avec un statut **C** : ~/work/projet1$ svn up C dev/dslice/vendor/NEWS Et dans ce cas Subversion va créer des fichier reflétant les différentes versions et vous laisse prendre la décision: NEWS.mine, NEW.r, NEWS.r. Si la portion du fichier source de conflit est réduite, le fichier lui-même sera modifié par Subversion qui insérera des marqueurs pour la délimiter. Quand un conflit est résolut, assurez-vous que ces fichiers temporaires de résolution de conflits sont supprimés ou demandez à Subersion : ~/work/projet1$ svn resolved dev/dslice/vendor/NEWS **Il faut toujours résoudre les conflits** avant de pouvoir continuer à travailler. ===== Conflits (commit) ===== Il s'agit du même problème que précédemment: si vous publiez une modification sur un fichier alors qu'un collègue vous a doublé, Subversion va annuler votre //commit//. Vous devez alors effectuer un //update// pour obtenir la nouvelle version, résoudre le conflit, puis recommencer le //commit//. ===== Utilitaires ===== Pour obtenir un historique des modification en un point de l'arborescence de votre projet, ou sur un fichier précis : ~/work/projet1$ svn log ~/work/projet1$ svn log dev/dslice/vendor/NEWS Pour abandonner vos modifications et revenir à la version d'un fichier lors de votre dernier //update// : ~/work/projet1$ svn revert dev/dslice/vendor/NEWS N'effacez pas ou ne renommez pas directement un fichier sous contrôle de Subversion, ce dernier ne pourra pas détecter la modification. Signalez votre intention à Subversion qui fera le reste : ~/work/projet1$ svn delete README.txt ~/work/projet1$ svn rename includes include