Il est temps de passer de l'abstrait au concret. Dans cette section, nous vous montrons des exemples réels d'utilisation de Subversion.
Tout au long de ce livre, Subversion utilise des URL pour identifier des fichiers et des répertoires suivis en version au sein de dépôts Subversion. Pour la plupart, ces URL utilisent la syntaxe standard, permettant de spécifier les noms des serveurs et les numéros de port à l'intérieur même de l'URL :
$ svn checkout http://svn.exemple.com:9834/depot …
Mais il existe quelques nuances dans la gestion des URL
par Subversion qui doivent être notées. Par exemple, les URL
ayant pour méthode d'accès file://
(utilisée pour les dépôts locaux) doivent posséder, en accord
avec les conventions, soit un nom de serveur
localhost
, soit pas de nom de serveur
du tout :
$ svn checkout file:///var/svn/depot … $ svn checkout 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 :
C:\> svn checkout file:///X:/var/svn/depot … C:\> svn checkout "file:///X|/var/svn/depot" …
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 »). De plus, 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 (\
).
Note | |
---|---|
Les URL Subversion |
Enfin, il faut noter que le client Subversion encode automatiquement les URL en cas de besoin, exactement comme le fait un navigateur web. Par exemple, si une URL contient un espace ou un caractère ASCII spécial, comme dans ce qui suit :
$ svn checkout "http://hote/chemin avec espace/projet/españa"
alors Subversion banalise les caractères spéciaux et se comporte comme si vous aviez tapé :
$ svn checkout http://hote/chemin%20avec%20espace/projet/espa%C3%B1a
Si l'URL contient des espaces, prenez bien soin de la placer entre guillemets, pour que votre shell traite le tout comme un unique argument du programme svn.
Vous avez déjà découvert ce que sont les copies de travail ; nous allons maintenant vous expliquer comment le client Subversion les crée et les utilise.
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 incorporera jamais les changements d'autres personnes ni ne rendra 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).
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 répertoire
de votre copie de travail contient un sous-répertoire appelé
.svn
, aussi appelé répertoire
administratif de votre copie de travail. Les
fichiers de chacun de ces répertoires administratifs 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.
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.6, « 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 entier.c bouton.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 va voir 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.
Une opération svn commit publie les modifications d'un nombre quelconque de fichiers et de répertoires en une seule opération atomique. Dans votre copie de travail, vous pouvez modifier le contenu des fichiers : créer, supprimer, renommer et copier fichiers et répertoires ; puis propager un ensemble de modifications en une seule transaction atomique.
Par « transaction atomique », on entend simplement ceci : soit toutes les modifications sont propagées dans le dépôt, soit aucune ne l'est. Subversion tente de conserver cette atomicité aussi bien face à des « plantages » de programmes, de systèmes d'exploitation ou de réseau, que face aux actions des autres utilisateurs.
Chaque fois que le dépôt accepte une propagation, ceci crée un nouvel état de l'arborescence du système de fichiers, appelé révision. Un numéro unique est associé à chaque révision, correspondant au numéro de la révision précédente augmenté de 1. La révision initiale d'un dépôt fraîchement créé porte le numéro 0 et ne consiste en rien d'autre qu'un répertoire racine vide.
La Figure 1.7, « Le dépôt » offre une vue intéressante du dépôt. Imaginez un tableau de numéros de révisions, commençant à 0 et s'étirant de la gauche vers la droite. Chaque numéro de révision correspond à une arborescence de système de fichiers située en-dessous de lui et chaque arborescence est une photo, un « instantané » (« snapshot » en anglais) du dépôt prise après une propagation.
Il est important de noter que les copies de travail ne correspondent pas toujours à une unique révision du dépôt ; elles peuvent contenir des fichiers provenant de plusieurs révisions différentes. Par exemple, supposons que vous extrayiez une copie de travail d'un dépôt dont la révision la plus récente est la numéro 4 :
calc/Makefile:4 integer.c:4 button.c:4
À cet instant, le répertoire de travail correspond
exactement à la révision 4 du dépôt. Néanmoins, supposons que
vous modifiiez bouton.c
et que vous
propagiez cette modification. En supposant qu'aucune autre
propagation n'a eu lieu, votre propagation crée la
révision 5 du dépôt et votre copie de travail ressemble
maintenant à ceci :
calc/Makefile:4 entier.c:4 bouton.c:5
Supposons maintenant qu'à ce moment précis, Sally propage
une modification d'entier.c
, créant la
révision 6. Si vous utilisez svn update
pour mettre à jour votre copie de travail, elle ressemble alors
à ceci :
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.
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 :
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 fera rien, un appel à svn update sur le fichier ne fera rien non plus.
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 permettra de publier vos modifications et un appel à svn update ne fera rien.
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 fera rien et un appel à svn update incorporera les dernières modifications dans votre copie de travail.
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 la tâche de résoudre le conflit.
Tout ceci peut sembler compliqué à gérer mais la commande svn status vous indique dans quel état se trouve n'importe quel élément de votre copie de travail. Pour plus d'informations sur cette commande, référez-vous à la section intitulée « Avoir une vue d'ensemble des changements effectués ».
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. Malheureusement, cette flexibilité a tendance à embrouiller un certain nombre de nouveaux utilisateurs. Si l'exemple précédent contenant des révisions mixtes vous laisse perplexe, voici une amorce d'explication à la fois sur les raisons pour lesquelles cette fonctionnalité existe et sur la façon de l'utiliser.
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.
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 « Affichage de l'historique »). 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é.
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.
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.