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.
Il existe de nombreux usages pour la création et la fusion des branches ; ce paragraphe décrit les plus courants.
Le plus souvent, la gestion de versions est utilisée pour le développement de logiciels, voici donc un coup d'œil rapide à deux des modèles les plus courants de création et de fusion de branches utilisés par les équipes de programmeurs. Si vous ne vous servez pas de Subversion pour développer des logiciels, n'hésitez pas à sauter ce paragraphe. Si vous êtes un développeur de logiciels qui utilise la gestion de versions pour la première fois, soyez très attentifs, car ces modèles sont souvent considérés comme des bonnes pratiques par les développeurs plus expérimentés. Ces procédures ne sont pas spécifiques à Subversion ; elles sont applicables à tout système de gestion de versions. Néanmoins, les voir explicitées en termes Subversion peut aider.
En général un logiciel suit un cycle de vie classique, répétant les trois étapes suivantes en boucle : code, test, publication. Il y a deux problèmes avec ce processus. Premièrement, les développeurs doivent continuer à écrire de nouvelles fonctionnalités pendant que les équipes d'assurance qualité prennent le temps de tester des versions supposées stables du logiciel. Les nouveaux développements ne peuvent pas s'arrêter pendant que le logiciel est en cours de test. Deuxièmement, l'équipe doit presque toujours effectuer le support des versions anciennes et publiées du logiciel ; si un bogue est découvert dans le code le plus récent, il existe probablement aussi dans les versions qui ont été publiées et les clients voudront obtenir le correctif pour ce bogue sans avoir à attendre la publication d'une nouvelle version majeure.
C'est là où la gestion de versions peut s'avérer utile. La procédure standard ressemble à ceci :
Les développeurs propagent tout nouveau
travail vers le tronc. Les modifications
quotidiennes sont propagées vers
/trunk
: nouvelles
fonctionnalités, corrections de bogues, etc.
Le tronc est copié vers une branche « de
publication ». Lorsque l'équipe estime que
le logiciel est prêt à être publié (disons en version 1.0),
/trunk
peut être copié vers
/branches/1.0
.
Les équipes continuent à travailler en
parallèle. Une équipe commence à tester
rigoureusement la branche de publication, pendant qu'une
autre équipe continue avec les nouvelles tâches (disons pour
la version 2.0) sur /trunk
. Si des
bogues sont découverts dans l'un ou l'autre des
emplacements, les correctifs sont reportés de l'un à l'autre
selon les besoins. Il arrive cependant un moment où même ce
processus s'arrête. La branche est « gelée » pour
les tous derniers tests juste avant publication.
La branche est étiquetée et
publiée. Quand les tests sont terminés,
/branches/1.0
est copiée vers
/tags/1.0.0
en tant que cliché de
référence. L'étiquette est exportée et livrée aux
clients.
La branche est gérée au fil du
temps. Pendant que le travail continue sur
/trunk
en vue de la version 2.0, les
correctifs de bogues continuent à être reportés de
/trunk
à
/branches/1.0
. Lorsque suffisamment de
correctifs se sont accumulés, les responsables peuvent
décider de publier une version 1.0.1 :
/branches/1.0
est copiée vers
/tags/1.0.1
et cette étiquette est
exportée et publiée.
Ce processus entier se répète au fur et à mesure que le logiciel gagne en maturité : quand le travail pour la version 2.0 est terminé, une nouvelle branche de publication 2.0 est créée, testée, étiquetée et finalement publiée. Au bout de quelques années, le dépôt finit par avoir un certain nombre de branches de publication en mode « maintenance » et un certain nombre d'étiquettes représentant les versions finales publiées.
Une branche fonctionnelle est
la sorte de branche qui est l'exemple dominant dans ce chapitre
(celle sur laquelle vous travailliez pendant que Sally
continuait à travailler sur /trunk
). C'est
une branche temporaire créée pour travailler sur un changement
complexe sans interférer avec la stabilité de
/trunk
. À la différence des branches de
publication (dont le support doit parfois être prolongé très
longtemps), les branches fonctionnelles naissent, sont utilisées
pendant un temps, sont fusionnées vers le tronc et sont
finalement supprimées. Elles ont une utilité limitée dans le
temps.
Encore une fois, les stratégies varient énormément au
sujet du moment approprié pour créer une branche fonctionnelle.
Certains projets n'utilisent jamais de branche
fonctionnelle : n'importe qui peut propager des
modifications à /trunk
. L'avantage de ce
système est qu'il est simple : personne n'a besoin d'être
formé aux branches ou aux fusions. L'inconvénient est que le
code du tronc est souvent instable ou inutilisable. D'autres
projets utilisent les branches à l'extrême : une
modification n'est jamais propagée
directement dans le tronc. Même les modifications les plus
triviales sont faites au sein d'une branche à courte durée de
vie, vérifiées attentivement, puis fusionnées vers le tronc.
La branche est ensuite supprimée. Ce système garantit que le
tronc restera exceptionnellement stable et utilisable à tout
moment, mais aux dépens des coûts de gestion liés à cette
procédure très lourde.
En général, les projets choisissent une approche à mi-chemin
entre les deux. Ils insistent généralement pour qu'à tout
moment /trunk
puisse être compilé et
passe avec succès les tests de régression. Une branche
fonctionnelle n'est nécessaire que quand une modification
nécessite un grand nombre de propagations susceptibles de
déstabiliser le tronc. Une bonne méthode empirique est de se
poser la question suivante : si le développeur
travaillait pendant plusieurs jours en isolation et ensuite
propageait cette grosse modification en une seule fois
(afin que /trunk
ne soit jamais
déstabilisé), est-ce que ce serait une modification trop
grosse à vérifier ? Si la réponse à cette question est
« oui », alors la modification devrait être
développée sur une branche fonctionnelle. Au fur et à mesure
que le développeur propage ses modifications incrémentales dans
la branche, elles peuvent facilement être vérifiées par ses
pairs.
Finalement, il reste la question de savoir quelle est la meilleure méthode pour garder une branche synchronisée avec le tronc au fur et à mesure que le travail avance. Comme nous l'avons mentionné précédemment, il est très risqué de travailler sur une branche pendant des semaines ou des mois ; le tronc continuera sûrement à recevoir des modifications, au point que les deux lignes de développement risquent de s'éloigner tellement l'une de l'autre qu'essayer de fusionner la branche vers le tronc devienne un cauchemar.
Le mieux pour éviter une telle situation est de fusionner régulièrement les modifications du tronc vers la branche. Faites-en une habitude : une fois par semaine, fusionnez les modifications du tronc de la semaine précédente vers la branche.
Le moment arrivera où vous serez prêt à fusionner la branche fonctionnelle « synchronisée » vers le tronc. Commencez donc par effectuer une dernière fusion des modifications les plus récentes du tronc vers la branche. Une fois que c'est fait, les dernières versions de la branche et du tronc sont absolument identiques, mises à part vos propres modifications sur la branche. Vous êtes alors en mesure de lancer une fusion automatique de réintégration de la branche vers le tronc :
$ cd copie-de-travail-du-tronc $ svn update À la révision 1910. $ svn merge ^/calc/branches/ma-branche --- Fusion des différences des URLs du dépôt vers '.': U reel.c U entier.c A nouveau-dossier A nouveau-dossier/nouveau-fichier U . …
Une autre façon de concevoir ce modèle est d'imaginer que votre synchronisation hebdomadaire du tronc vers la branche est analogue au lancement de svn update dans une copie de travail, tandis que l'étape finale de fusion est analogue au lancement de svn commit depuis une copie de travail. Après tout, une copie de travail n'est rien d'autre qu'une branche privée très superficielle : c'est une branche qui n'est capable de ne contenir qu'une seule modification à la fois.