This text is a work in progress—highly subject to change—and may not accurately describe any released version of the Apache™ Subversion® software. Bookmarking or otherwise referring others to this page is probably not such a smart idea. Please visit http://www.svnbook.com/ for stable versions of this book.

Subversion en action

Nous avons déjà indiqué que Subversion est un logiciel de gestion de versions moderne et en réseau. Comme décrit dans la section intitulée « Notions générales de la gestion de versions », un dépôt sert de cœur de stockage pour les données suivies en versions et c'est par l'intermédiaire de copies de travail que les utilisateurs et les logiciels qu'ils manipulent interagissent avec les données. Dans cette section, nous allons commencer par introduire les différentes manières dont Subversion implémente la gestion de versions.

Dépôts Subversion

Subversion implémente le concept de dépôt comme tout autre logiciel de gestion de versions moderne. Contrairement à une copie de travail, un dépôt Subversion est une entité abstraite qui ne peut être manipulée pratiquement que par les bibliothèques et les propres outils de Subversion. Comme la plupart des interactions d'un utilisateur de Subversion se font par l'intermédiaire du client Subversion et qu'elles ont lieu dans le contexte de la copie de travail, ce livre traite en une grande partie de la copie de travail et des actions que l'on peut y appliquer. Pour les détails du dépôt, vous pouvez cependant vous référer au Chapitre 5, Administration d'un dépôt.

[Avertissement] Avertissement

Dans Subversion, l'entité que possède chaque utilisateur du logiciel — le répertoire des fichiers suivis en versions ainsi que les métadonnées qui permettent au système de tracer les données et de communiquer avec le serveur — s'appelle la copie de travail. Bien que d'autres logiciels de gestion de versions utilisent le terme de « dépôt » pour l'entité côté client, c'est à la fois incorrect et une source fréquente de confusion d'utiliser ce terme dans ce sens là dans le contexte de Subversion.

Les copies de travail sont abordées plus loin, dans la section intitulée « Copies de travail ».

Révisions

Une opération svn commit propage (c'est-à-dire communique au serveur) les modifications d'un nombre quelconque de fichiers et de répertoires en une seule opération atomique. Par opération atomique, nous entendons que, soit toutes les modifications sont prises en compte par le dépôt, soit rien n'est pris en compte. Subversion essai d'être robuste dans ce concept d'atomicité, même en cas de plantage du programme, du système, de problèmes réseau ou d'actions de la part des autres utilisateurs.

Chaque fois que le dépôt accepte une propagation (c'est-à-dire une opération svn commit), il crée un nouvel état de l'arborescence du système de fichiers que l'on appelle révision. À Chaque révision est associé un entier naturel unique, immédiatement supérieur à l'entier associé à la révision précédente. La révision initiale d'un dépôt nouvellement créé à pour numéro 0 et n'est constituée que d'un répertoire racine vide.

La Figure 1.6, « L'évolution de l'arborescence au cours du temps » illustre une manière intéressante de se représenter le dépôt. Imaginez un tableau de numéros de révisions, commençant à zéro et s'étirant de la gauche vers la droite. À Chaque numéro de révision est suspendue une arborescence du système de fichiers, qui est une photo, un « instantané » (snapshot en anglais) du dépôt prise après une propagation.

Figure 1.6. L'évolution de l'arborescence au cours du temps

L'évolution de l'arborescence au cours du temps

URL des dépôts Subversion

les logiciels côté client de Subversion utilisent des URL pour identifier les fichiers et répertoires suivis en versions dans les dépôts Subversion. Pour leur grande partie, ces URL utilisent la syntaxe standard, permettant de spécifier le nom du serveur et le numéro de port directement dans l'URL.

  • http://svn.exemple.com/svn/projet
  • http://svn.exemple.com:9834/depot

Les URL de dépôts Subversion ne se limitent pas au domaine http://. Comme Subversion permet à ses clients de dialoguer de différentes manières avec les dépôts, les URL utilisées pour se connecter diffèrent subtilement en fonction du protocole employé. La Tableau 1.1, « Les différents motifs d'URL pour l'accès aux dépôts » décrit la correspondance entre les différents motifs d'URL et les méthodes d'accès aux dépôts. Pour plus de détails sur les options du serveur Subversion, reportez-vous au Chapitre 6, Configuration du serveur.

Tableau 1.1. Les différents motifs d'URL pour l'accès aux dépôts

Schéma Méthode d'accès
file:/// Accès direct au dépôt (sur disque local)
http:// Accès par protocole WebDAV sur un serveur Apache disposant d'un connecteur Subversion
https:// Comme http://, avec une encapsulation SSL
svn:// Accès via un protocole personnalisé à un serveur svnserve
svn+ssh:// Comme svn://, avec une encapsulation dans un tunnel SSH

Le support des URL par Subversion possède quelques particularités notables. Par exemple, les URL contenant la méthode d'accès file:// (utilisée pour les dépôts locaux) doivent spécifier, par convention, soit le nom de serveur localhost, soit pas de nom de serveur :

  • file:///var/svn/depot
  • file://localhost/var/svn/depot

D'autre part, les utilisateurs du procédé file:// sur les plateformes Windows doivent se servir d'une syntaxe qui est un « standard » officieux pour accéder à leurs dépôts se trouvant sur la même machine mais sur un disque différent du disque de travail habituel du client. Les deux syntaxes de chemin d'URL suivantes fonctionnent, X étant le disque sur lequel le dépôt se trouve :

  • file:///X:/var/svn/depot
  • file:///X|/var/svn/depot

Remarquez qu'une URL utilise des barres obliques (/) alors que la forme native (non-URL) d'un chemin sous Windows utilise des barres obliques inversées (\). Notez aussi que, dans la seconde syntaxe, vous devez entourer l'URL de guillemets pour éviter que la barre verticale ne soit interprétée comme un symbole de redirection (un « pipe »).

[Note] Note

Les URL Subversion file:// ne peuvent pas être utilisées dans un navigateur web classique de la même façon qu'une URL file:// habituelle. Lorsque vous essayez de visualiser une URL file:// dans un navigateur web classique, il lit et affiche le contenu du fichier situé à cet emplacement en interrogeant directement le système de fichiers. Cependant, les ressources de Subversion existent dans un système de fichier virtuel (cf. la section intitulée « Couche dépôt ») et votre navigateur ne comprend pas comment interagir avec ce système de fichiers.

Il faut noter que le client Subversion encode automatiquement les URL en cas de besoin, exactement comme le fait un navigateur web. Par exemple, l'URL http://host/path with space/project/españa — qui contient à la fois des espaces et des caractères non ASCII— est automatiquement interprétée par Subversion comme si vous aviez fourni http://host/path%20with%20space/project/espa%C3%B1a. Si l'URL contient des espaces, prenez bien soin de les placer entre guillemets dans la ligne de commande afin que le shell traite le tout comme un unique argument du programme.

Il existe aussi une exception à la gestion des URL par Subversion qui s'applique à la gestion des chemins locaux dans beaucoup de contextes. Si le dernier élément de l'URL ou du chemin contient le signe arobase (@), vous devez utiliser une syntaxe particulière, décrite dans la section intitulée « Révisions pivots et révisions opérationnelles », afin que Subversion prenne proprement en compte l'adresse de cette ressource.

Dans Subversion 1.6, une nouvelle notation, dite syntaxe avec chapeau (^) a été introduite comme raccourci pour « l'URL du répertoire racine du dépôt ». Par exemple, vous pouvez utiliser ^tags/gros-sandwich pour désigner l'URL du répertoire /tags/gros-sandwich à la racine du dépôt. Une telle URL est appelée URL relative au dépôt. Remarquez que cette syntaxe d'URL ne fonctionne que si votre répertoire de travail est une copie de travail, le client texte interactif récupérant l'URL de la racine du dépôt dans les métadonnées de la copie de travail. Notez aussi que lorsque vous voulez faire référence précisément au répertoire racine du dépôt, vous devez utiliser ^/ (avec la barre oblique terminale) et non simplement ^. Les utilisateurs sous Windows ne doivent pas oublier que le caret est un caractère d'échappement pour ce système. En conséquence, vous devez utiliser un double caret ^^ si votre client Subversion tourne sur une machine Windows.

Copies de travail

Une copie de travail Subversion est une arborescence classique de répertoires de votre système local, contenant un ensemble de fichiers. Vous pouvez éditer ces fichiers comme vous le voulez et, s'il s'agit de code source, vous pouvez compiler votre programme à partir de ceux-ci de la façon habituelle. Votre copie de travail est votre espace de travail personnel privé : Subversion n'y incorpore jamais les changements d'autres personnes ni ne rend jamais disponibles vos propres changements à d'autres personnes tant que vous ne lui demanderez pas explicitement de le faire. Vous pouvez même avoir plusieurs copies de travail d'un même projet.

Après que vous ayez apporté quelques modifications aux fichiers de votre copie de travail et vérifié qu'elles fonctionnent correctement, Subversion vous fournit des commandes pour « publier » vos changements vers les autres personnes qui travaillent avec vous sur votre projet (en les transmettant au dépôt). Si d'autres personnes publient leurs propres modifications, Subversion vous fournit des commandes pour fusionner ces changements dans votre copie de travail (en les obtenant du dépôt). Remarquez que le dépôt central joue le rôle d'intermédiaire pour les changements de tout le monde dans Subversion ; les modifications ne passent pas directement d'une copie de travail à une autre copie de travail dans le processus classique.

Une copie de travail contient également quelques fichiers supplémentaires, créés et gérés par Subversion, pour l'aider à effectuer ces opérations. En particulier, chaque copie de travail contient un sous-répertoire nommé .svn, aussi connu sous l'appellation de répertoire administratif de votre copie de travail. Les fichiers de ce répertoire administratif permettent à Subversion d'identifier quels fichiers contiennent des modifications non-publiées et quels fichiers sont périmés vis-à-vis du travail des autres personnes.

[Note] Note

Avant la version 1.7, Subversion plaçait un répertoire .svn dans chaque sous-répertoire géré en versions de la copie de travail. Subversion 1.7 utilise une approche complètement nouvelle pour stocker, suivre et travailler avec les métadonnées, et le changement le plus visible de cette approche est qu'il n'existe dans la copie de travail qu'un seul sous-répertoire .svn situé à la racine de la copie de travail.

Fonctionnement de la copie de travail

Pour chaque fichier d'un répertoire de travail, Subversion enregistre deux informations essentielles dans la zone administrative .svn/ :

  • la révision sur laquelle votre fichier de travail est basé (qui est appelée la révision de travail du fichier) et

  • la date et l'heure de la dernière mise à jour de la copie locale depuis le dépôt

À partir de ces informations, en dialoguant avec le dépôt, Subversion est capable de déterminer dans lequel des quatre états suivants se trouve un fichier de travail 

Inchangé et à jour

Le fichier est inchangé dans le répertoire de travail et aucune modification de ce fichier n'a été propagée vers le dépôt depuis sa révision de travail. Un appel à svn commit sur le fichier ne fait rien, un appel à svn update sur le fichier ne fait rien non plus.

Modifié localement et à jour

Le fichier a été modifié dans le répertoire de travail et aucune modification du fichier n'a été propagée dans le dépôt depuis la dernière mise à jour. Il existe des modifications locales qui n'ont pas été propagées vers le dépôt, donc un appel à svn commit sur le fichier permet de publier vos modifications et un appel à svn update ne fait rien.

Inchangé et périmé

Le fichier n'a pas été modifié dans le répertoire de travail mais a changé dans le dépôt. Le fichier devra être mis à jour à un moment ou à un autre, pour l'amener au niveau de la dernière révision publique. Un appel à svn commit sur le fichier ne fait rien et un appel à svn update incorpore les dernières modifications dans votre copie de travail.

Modifié localement et périmé

Le fichier a été modifié à la fois dans le répertoire de travail et dans le dépôt. Un appel à svn commit sur le fichier va échouer, renvoyant comme erreur « Périmé » (out-of-date en anglais). Le fichier doit d'abord être mis à jour ; un appel à svn update va tenter de fusionner les modifications publiques avec les modifications locales. Si Subversion ne parvient pas à réaliser automatiquement cette fusion de manière crédible, il va laisser à l'utilisateur le soin de résoudre le conflit.

Actions de base sur la copie de travail

Un dépôt Subversion contient bien souvent les fichiers (ou code source) de plusieurs projets ; habituellement, chaque projet est un sous-répertoire de l'arborescence du système de fichiers du dépôt. Dans cette situation, la copie de travail d'un utilisateur correspond à une sous-arborescence particulière du dépôt.

Par exemple, supposons que votre dépôt contienne deux projets logiciels, paint et calc. Chaque projet réside dans son propre sous-répertoire racine, comme indiqué dans la Figure 1.7, « Système de fichiers du dépôt ».

Figure 1.7. Système de fichiers du dépôt

Système de fichiers du dépôt

Pour obtenir une copie de travail, vous devez extraire une sous-arborescence du répertoire (le terme « extraire », check out en anglais, peut vous faire penser que cela a quelque chose à voir avec verrouiller ou réserver des ressources, mais ce n'est pas le cas ; cela crée simplement pour vous une copie privée du projet). Par exemple, si vous extrayez /calc, vous obtenez une copie de travail qui ressemble à ceci :

$ svn checkout http://svn.exemple.com/depot/calc
A    calc/Makefile
A    calc/entier.c
A    calc/bouton.c
Révision 56 extraite.
$ ls -A calc
Makefile  bouton.c entier.c .svn/
$

Les lettres A qui s'affichent dans la marge de gauche indiquent que Subversion est en train d'ajouter des éléments dans votre copie de travail. Vous avez désormais votre copie personnelle du répertoire /calc du dépôt, avec une entrée supplémentaire, .svn, qui contient des informations complémentaires nécessaires à Subversion, comme évoqué précédemment.

Supposons que vous fassiez des modifications à bouton.c. Comme le répertoire .svn se souvient de la date de modification et du contenu du fichier original, Subversion peut en déduire que vous avez modifié le fichier. Néanmoins, Subversion ne rend pas vos modifications publiques tant que vous ne lui dites pas de le faire. L'action de publication de vos modifications est plus communément appelée propagation (« commit » ou check in en anglais et, parfois, archivage ou livraison en français) des modifications au sein du dépôt.

Pour rendre publiques vos modifications, vous pouvez utiliser la commande Subversion svn commit :

$ svn commit bouton.c -m "Coquille corrigée dans bouton.c."
Ajout        bouton.c
Transmission des données .
Révision 57 propagée.
$

À présent, vos modifications de bouton.c ont été propagées au sein du dépôt, avec un commentaire décrivant ces changements (« vous avez corrigé une coquille »). Si un autre utilisateur extrait une copie de travail de /calc/, il verra vos modifications dans la dernière version du fichier.

Supposons que vous ayez une collaboratrice, Sally, qui a extrait une copie de travail de /calc en même temps que vous. Lorsque vous propagez votre modification de bouton.c, la copie de travail de Sally reste inchangée ; Subversion ne modifie les copies de travail qu'à la demande des utilisateurs.

Pour mettre son projet à jour, Sally peut demander à Subversion de mettre à jour (update en anglais) sa copie de travail, en utilisant la commande svn update. Cela va intégrer vos modifications dans sa copie de travail, ainsi que celles qui ont été envoyées par d'autres personnes depuis qu'elle l'avait extraite.

$ pwd
/home/sally/calc

$ ls -A
Makefile bouton.c entier.c .svn/
$ svn update
U    bouton.c
Actualisé à la révision 57.
$

En sortie, la commande svn update indique que Subversion a mis à jour le contenu de bouton.c. Remarquez que Sally n'a pas eu besoin de spécifier quels fichiers devaient être mis à jour ; Subversion utilise les informations contenues dans le répertoire .svn, ainsi que d'autres informations en provenance du dépôt, pour décider quels fichiers doivent être mis à jour.

Copies de travail mixtes, à révisions mélangées

Un principe général de Subversion est d'être aussi flexible que possible. Un type particulier de flexibilité est la capacité d'avoir une copie de travail contenant des fichiers et des répertoires avec un mélange de différents numéros de révision. Les copies de travail ne correspondent pas toujours à une révision unique du dépôt  elles peuvent contenir des fichiers qui sont à des révisions différentes. Par exemple, supposons que vous extrayez une copie de travail d'un dépôt dont la révision la plus récente porte le numéro 4 :


calc/
   Makefile:4

   entier.c:4
   bouton.c:4

Tel quel, le répertoire de travail correspond exactement à la révision 4 du dépôt. Maintenant, supposons que vous modifiez le fichier bouton.c et que vous propagiez cette modification. Si aucune autre propagation n'a eu lieu entre temps, votre propagation crée la révision 5 du dépôt et votre copie de travail ressemble à :


calc/
   Makefile:4

   entier.c:4
   bouton.c:5

Supposons que, à ce moment ci, Sally propage une modification à entier.c, créant ainsi la révision 6. Si vous faites svn update pour mettre à jour votre copie de travail, elle ressemble à :


calc/
   Makefile:6

   entier.c:6
   bouton.c:6

Les modifications apportées par Sally à entier.c apparaissent dans votre copie de travail et vos modifications sont toujours présentes dans bouton.c. Dans cet exemple, le texte de Makefile est identique dans les révisions 4, 5 et 6 mais Subversion marque votre copie de travail de Makefile comme étant à la révision 6 pour indiquer qu'elle est à jour. Ainsi, quand vous effectuez une mise à jour au niveau de la racine de votre copie de travail, celle-ci correspond en général à une révision donnée du dépôt.

Mise à jour et propagation sont deux opérations distinctes

Une des règles fondamentales de Subversion est que l'action de « pousser » ne déclenche pas une action de « tirer », ni l'inverse. Le simple fait que vous soyez prêt à soumettre vos nouvelles modifications au dépôt ne veut pas dire que vous êtes prêts à recevoir les modifications d'autres personnes. Et si vous avez de nouvelles modifications encore en cours, alors svn update fusionne élégamment les changements du dépôt avec les vôtres, plutôt que de vous forcer à les publier.

Le principal effet secondaire de cette règle est que la copie de travail a de la comptabilité supplémentaire à effectuer pour suivre les mélanges de révision et également être tolérante vis-à-vis de l'ensemble. Cela est rendu encore plus difficile par le fait que les répertoires eux-mêmes sont suivis en versions.

Par exemple, supposons que vous ayez une copie de travail qui soit intégralement à la révision 10. Vous éditez le fichier truc.html et réalisez ensuite un svn commit qui crée la révision 15 dans le dépôt. Après que la propagation ait réussi, nombreux sont ceux parmi les nouveaux utilisateurs qui s'attendraient à ce que toute la copie de travail soit à la révision 15, mais ce n'est pas le cas ! Un certain nombre de modifications ont pu avoir lieu dans le dépôt entre les révisions 10 et 15. Le client ne sait rien de ces changements qui ont été apportés au dépôt, puisque vous n'avez pas encore exécuté la commande svn update et la commande svn commit ne récupère pas les nouvelles modifications. D'un autre côté, si la commande svn commit téléchargeait automatiquement les modifications les plus récentes, alors il serait possible d'avoir toute la copie de travail à la révision 15 mais, dans ce cas, nous enfreindrions la règle fondamentale selon laquelle « pousser » et « tirer » doivent demeurer des actions distinctes. Ainsi, la seule chose que le client Subversion peut faire en toute sécurité est de marquer le fichier truc.html, et lui seulement, comme étant à la révision 15. Le reste de la copie de travail reste à la révision 10. Seule l'exécution de la commande svn update permet de récupérer les dernières modifications et de marquer la copie de travail comme étant à la révision 15.

Des révisions mélangées sont normales

Le fait est qu'à chaque fois que vous exécutez la commande svn commit, votre copie de travail se retrouve composée d'un mélange de révisions. Les éléments que vous venez juste de propager sont marqués comme ayant un numéro de révision plus élevé que tous les autres. Après plusieurs propagations (sans mise à jour entre-temps), votre copie de travail va contenir tout un mélange de révisions. Même si vous êtes la seule personne à utiliser le dépôt, vous constaterez quand même ce phénomène. Pour étudier votre propre mélange de révisions de travail, utilisez la commande svn status avec l'option --verbose (voir la section intitulée « Avoir une vue d'ensemble des changements effectués » pour plus d'informations).

Souvent, les nouveaux utilisateurs n'ont pas du tout conscience que leur copie de travail contient des révisions mélangées. Cela peut être déroutant car beaucoup de commandes client sont sensibles à la révision de travail de l'élément qu'elles examinent. Par exemple, la commande svn log est utilisée pour afficher l'historique des modifications d'un fichier ou d'un répertoire (cf. la section intitulée « Afficher l'historique des modifications »). Lorsque l'utilisateur appelle cette commande sur un objet de la copie de travail, il s'attend à obtenir l'historique complet de celui-ci. Mais si la révision de travail de l'objet est assez ancienne (souvent parce que svn update n'a pas été lancé depuis un certain temps), alors c'est l'historique de l'ancienne version de l'objet qui est affiché.

Les mélanges de révisions sont utiles

Si votre projet est suffisamment complexe, vous allez découvrir qu'il est parfois pratique d'effectuer un retour en arrière forcé (c'est-à-dire de faire une mise à jour vers une version plus ancienne que celle que vous avez déjà) sur certaines parties de votre copie de travail vers des révisions plus anciennes ; vous apprendrez comme le faire dans le Chapitre 2, Utilisation de base. Vous avez peut-être envie de tester une version précédente d'un sous-module contenu dans un sous-répertoire ou bien de comprendre comment un bogue est apparu pour la première fois dans un fichier donné. C'est le côté « machine à voyager dans le temps » d'un logiciel de gestion de versions, la fonctionnalité qui vous permet de déplacer n'importe quelle partie de votre copie de travail en avant ou en arrière dans le temps.

Les mélanges de révisions ont des limites

Quelle que soit la façon dont vous utilisez les mélanges de révision dans votre copie de travail, il existe des limites à cette flexibilité.

Premièrement, vous ne pouvez pas propager la suppression d'un fichier ou d'un répertoire qui n'est pas complètement à jour. Si une version plus récente de l'élément existe dans le dépôt, votre tentative de suppression est rejetée, afin de vous empêcher de détruire accidentellement des modifications dont vous n'aviez pas encore connaissance.

Deuxièmement, vous ne pouvez propager la modification des métadonnées d'un répertoire que si celui-ci est complètement à jour. Vous apprendrez comment associer des « propriétés » à des éléments dans le Chapitre 3, Sujets avancés. La révision de travail d'un répertoire définit un ensemble précis d'entrées et de propriétés et propager la modification d'une propriété d'un répertoire périmé risquerait de détruire des propriétés dont vous n'aviez pas encore connaissance.

Enfin, à partir de Subversion 1.7, vous ne pouvez pas utiliser par défaut une copie de travail à révisions mélangées comme cible d'une opération de fusion ; cette limitation a été introduite pour prévenir certains problèmes qui apparaissent dans ce cas.