Rendu à ce chapitre, vous devriez avoir compris que chaque propagation crée une arborescence de fichiers entièrement nouvelle (appelée « révision ») dans le dépôt. Si ce n'est pas le cas, retournez vous informer sur les révisions dans la section intitulée « Révisions ».
Pour ce chapitre, nous reprendrons le même exemple qu'au
Chapitre 1, Notions fondamentales. Souvenez-vous que votre
collaboratrice Sally et vous partagez un dépôt qui contient
deux projets, paint
et
calc
. Notez cependant que dans la
Figure 4.2, « Structure initiale du dépôt », le dossier de
chaque projet contient désormais des sous-dossiers nommés
trunk
et branches
.
Les raisons de cette arborescence apparaîtront bientôt
clairement.
Comme avant, supposons que Sally et vous avez tous deux une
copie de travail du projet « calc ». Plus
spécifiquement, vous avez chacun une copie de travail de
/calc/trunk
. Tous les fichiers du projet
sont dans ce sous-dossier plutôt que dans
/calc
lui-même, parce que votre équipe a
décidé que la « ligne principale » de développement
du projet allait se situer
dans /calc/trunk
.
Disons que l'on vous a attribué la tâche d'implémenter une
fonctionnalité du logiciel qui prendra longtemps à écrire et
touchera à tous les fichiers du projet. Le problème immédiat est
que vous ne voulez pas déranger Sally, qui est en train de
corriger des bogues mineurs ici et là. Elle a besoin que la
dernière version du projet
(dans /calc/trunk
) demeure en permanence
utilisable. Si vous commencez à propager des changements petit
à petit, vous allez sûrement rendre les choses difficiles pour
Sally (ainsi que pour d'autres membres de l'équipe).
Une stratégie possible est de vous isoler : vous pouvez
arrêter de partager des informations avec Sally pendant une
semaine ou deux. C'est-à-dire commencer à modifier et à
réorganiser les fichiers dans votre copie de travail, mais
sans effectuer de propagation ni de mise à jour avant que vous
n'ayez complètement terminé la tâche. Cette stratégie comporte
certains risques. Premièrement,
ce n'est pas sans danger. La plupart des gens aiment propager
leurs modifications fréquemment, au cas où leur copie de travail
aurait un accident. Deuxièmement, ce n'est pas très flexible. Si
vous travaillez sur différents ordinateurs (vous avez peut-être
une copie de travail de /calc/trunk
sur
deux machines différentes), vous aurez besoin de transférer
manuellement vos changements entre les deux, ou bien de
travailler sur une seule machine. De la même façon, il est
difficile de partager vos changements en cours avec quelqu'un
d'autre. Une des « bonnes pratiques » du monde du
développement logiciel est de permettre à vos pairs de passer
votre travail en revue au fur et à mesure. Si personne n'a accès
à vos propagations intermédiaires, vous vous coupez d'éventuelles
critiques et risquez de partir dans une mauvaise direction
pendant des semaines avant que quelqu'un ne s'en aperçoive.
Enfin, quand vous en aurez fini avec tous vos changements,
vous pourriez avoir du mal à fusionner votre travail avec le
code du reste de l'équipe. Sally (et les autres) peuvent avoir
apporté de nombreux autres changements au dépôt, changements qui
seront difficiles à incorporer dans votre copie de travail,
notamment si vous lancez svn update après des
semaines d'isolation.
Une solution bien meilleure est de créer votre propre branche, ou ligne de développement, dans le dépôt. Ceci vous permettra de sauvegarder fréquemment votre travail un peu boiteux sans interférer avec vos collaborateurs ; vous pourrez toutefois partager une sélection d'informations avec eux. Vous découvrirez comment tout cela fonctionne exactement au fur et à mesure de ce chapitre.
Créer une branche est très simple : il s'agit juste de faire
une copie du projet dans le dépôt avec la commande
svn copy. Subversion est capable de copier
non seulement de simples fichiers, mais aussi des dossiers
entiers. Dans le cas présent, vous voulez faire une copie du
dossier /calc/trunk
. Où doit résider la
nouvelle copie ? Là où vous le désirez, cette décision faisant
partie de la gestion du projet. Supposons que votre équipe ait
pour convention de créer les branches dans la zone
/calc/branches
du dépôt et que vous
vouliez nommer votre branche
ma-branche-calc
. Vous créez alors un
nouveau dossier,
/calc/branches/ma-branche-calc
,
qui commence ainsi sa vie en tant que copie de
/calc/trunk
.
Vous avez peut-être déjà utilisé svn copy pour copier un fichier vers un autre à l'intérieur d'une copie de travail. Mais il peut aussi être utilisé pour effectuer une copie « distante » entièrement à l'intérieur du dépôt. Il suffit de copier une URL vers une autre :
$ svn copy http://svn.exemple.com/depot/calc/trunk \ http://svn.exemple.com/depot/calc/branches/ma-branche-calc \ -m "Création d'une branche privée à partir de /calc/trunk." Révision 341 propagée.
Cette commande entraîne une opération quasi-instantanée
dans le dépôt, créant un nouveau dossier à la révision 341.
Ce nouveau dossier est une copie de
/calc/trunk
, comme l'illustre la
Figure 4.3, « Dépôt avec nouvelle copie »
[21].
Bien qu'il soit aussi possible de créer une branche en
utilisant svn copy pour dupliquer un dossier
à l'intérieur de la copie de travail, cette technique n'est
pas recommandée. Elle peut s'avérer assez lente, en fait !
Copier un dossier côté client est une opération linéaire en
terme de durée, puisque chaque fichier et chaque dossier doit
être dupliqué sur le disque local. Copier un dossier sur le
serveur, par contre, est une opération dont la durée est
constante et c'est ainsi que la plupart des gens créent
des branches.
Maintenant que vous avez créé votre branche du projet, vous pouvez extraire une nouvelle copie de travail et commencer à l'utiliser :
$ svn checkout http://svn.exemple.com/depot/calc/branches/ma-branche-calc A ma-branche-calc/Makefile A ma-branche-calc/entier.c A ma-branche-calc/bouton.c Révision 341 extraite.
Cette copie de travail n'a rien de spéciale ; elle
correspond juste à un dossier différent du dépôt. Cependant,
quand vous propagerez vos modifications, Sally ne les verra
pas quand elle effectuera une mise à jour, car sa copie de
travail correspond à calc/trunk
(pensez
bien à lire la section intitulée « Parcours des branches » plus
loin dans ce chapitre : la commande
svn switch est une méthode alternative
pour créer une copie de travail d'une branche).
Imaginons qu'une semaine passe et que les propagations suivantes ont lieu :
Vous modifiez
/calc/branches/ma-branche-calc/bouton.c
,
ce qui crée la révision 342.
Vous modifiez
/calc/branches/ma-branche-calc/entier.c
,
ce qui crée la révision 343.
Sally modifie
/calc/trunk/entier.c
,
ce qui crée la révision 344.
À présent, deux lignes de développement indépendantes (voir
la Figure 4.4, « Historique des branches d'un fichier ») existent
pour entier.c
.
Les choses deviennent intéressantes quand on regarde
l'historique des modifications apportées à votre copie de
entier.c
:
$ pwd /home/utilisateur/ma-branche-calc $ svn log -v entier.c ------------------------------------------------------------------------ r343 | utilisateur | 2002-11-07 15:27:56 -0600 (jeu. 07 nov. 2002) | 2 lignes Chemins modifiés : M /calc/branches/ma-branche-calc/entier.c * entier.c: machiné le bidule. ------------------------------------------------------------------------ r341 | utilisateur | 2002-11-03 15:27:56 -0600 (jeu. 07 nov. 2002) | 2 lignes Chemins modifiés : A /calc/branches/ma-branche-calc (from /calc/trunk:340) Création d'une branche privée à partir de /calc/trunk. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (mar. 29 oct. 2002) | 2 lignes Chemins modifiés : M /calc/trunk/entier.c * entier.c: modifié une docstring. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (ven. 22 fev. 2002) | 2 lignes Chemins modifiés : A /calc/trunk/entier.c * entier.c: ajout du fichier dans ce projet. ------------------------------------------------------------------------
Notez bien que Subversion reprend tout l'historique du
entier.c
de votre branche à travers le
temps, remontant même au delà du point où il a été copié. Il
liste la création d'une branche en tant qu'élément de
l'historique, parce qu'entier.c
a été
copié implicitement lorsque calc/trunk
tout entier a été copié. Maintenant regardez ce qui se passe
quand Sally lance la même commande sur sa copie du
fichier :
$ pwd /home/sally/calc $ svn log -v entier.c ------------------------------------------------------------------------ r344 | sally | 2002-11-07 15:27:56 -0600 (jeu. 07 nov. 2002) | 2 lignes Chemins modifiés : M /calc/trunk/entier.c * entier.c: corrigé un ensemble de coquilles. ------------------------------------------------------------------------ r303 | sally | 2002-10-29 21:14:35 -0600 (mar. 29 oct. 2002) | 2 lignes Chemins modifiés : M /calc/trunk/entier.c * entier.c: modifié une docstring. ------------------------------------------------------------------------ r98 | sally | 2002-02-22 15:35:29 -0600 (ven. 22 fev. 2002) | 2 lignes Chemins modifiés : A /calc/trunk/entier.c * entier.c: ajout du fichier dans ce projet. ------------------------------------------------------------------------
Sally voit la modification due à sa propre révision 344, mais pas le changement que vous avez effectué dans la révision 343. Pour Subversion, ces deux propagations ont touché des fichiers différents dans des dossiers distincts. Néanmoins, Subversion indique bien que les deux fichiers partagent une histoire commune. Avant que la copie de branche n'ait été faite en révision 341, les fichiers ne faisaient qu'un. C'est pourquoi Sally et vous voyez tous les deux les modifications apportées en révisions 303 et 98.
Il y a deux leçons importantes à retenir de ce paragraphe. Premièrement, Subversion n'a pas de notion interne de branche — il sait seulement faire des copies. Quand vous copiez un dossier, le dossier qui en résulte n'est une « branche » que parce que vous le considérez comme tel. Vous aurez beau envisager ce dossier différemment ou le traiter différemment, pour Subversion c'est juste un dossier ordinaire auquel sont associées des informations extra-historiques.
Deuxièmement, à cause de ce mécanisme de copie, les
branches de Subversion existent en tant que
dossiers classiques du système de fichiers
du dépôt. En cela, Subversion diffère des autres systèmes
de gestion de versions, où les branches sont définies par
l'ajout d'« étiquettes » extra-dimensionnelles
à des groupes de fichiers. L'emplacement du dossier de votre
branche importe peu à Subversion. La plupart des équipes ont
pour convention de placer toutes les branches dans un dossier
/branches
, mais vous êtes libre
d'inventer la convention qui vous plaît.
[21] Subversion n'accepte pas les copies entre des dépôts distincts. Quand vous utilisez des URLs avec svn copy et svn move, vous ne pouvez copier que des éléments faisant partie du même dépôt.