L’index des leçons :
- Leçon 1 : la gestion de version
- Leçon 2 : qu’est-ce qu’un dépôt ?
- Leçon 3 : les logiciels ”clients”
- Leçon 4 : création d’un dépôt
- Leçon 5 : enregistrement de révision
- Leçon 6 : synchronisation de dépôts, mise à jour du répertoire de travail
- Leçon 7 : identifier les différences
- Leçon 8 : la gestion des branches
- Leçon 9 : la fusion de branche
- Leçon 10 : retour vers le passé
- Leçon 11 : patch et collaboration indirecte
Les branches
Nous avons jusqu’ici abordé uniquement la gestion de version linéaire, sur une seule branche. Il est temps désormais d’aborder cette notion particulière qui fait un des points forts de Mercurial (ou Git), la gestion de branche.
Qu’est-ce qu’une branche ? C’est un ensemble de révisions indépendant des autres branches. Ce principe est utile pour développer une version d’un logiciel, puis, une fois celle-ci publiée, continuer son développement en vue d’ajout de fonctionnalités futures, mais qu’en même temps vous souhaitez pouvoir corriger rapidement des erreurs signalées sur la version publiée (et donc y revenir facilement).
Cela peut aussi être utile pour explorer le développement d’une fonctionnalité alternative et redondante avec celle développée dans la branche principale. Au bout des deux développements vous pourrez alors sélectionner la voie idéale, voire même fusionner ces deux branches en une seule — ce qu’on appelle un merge, nous y viendrons à la leçon suivante.
En pratique
Je vais maintenant illustrer la façon de travailler avec deux branches à l’aide de MacHg. Prenez le temps de suivre pas à pas le déroulement des opérations et n’hésitez pas à reprendre du début si vous avez l’impression de perdre le fil. C’est un aspect pas toujours évident à saisir mais une fois que c’est le cas vous devriez ne plus avoir de problème de compréhension sur la gestion des dépôts Mercurial.
Si vous vous reportez à la fin de la leçon 6, vous devriez avoir 4 révisions dans votre dépôt, la dernière étant affublée d’un label default
. C’est ainsi qu’est nommée l’unique branche présente à la création d’un dépôt :
Afin de pouvoir développer et tester une fonctionnalité particulière de configuration j’ai choisi de créer une nouvelle branche nommée config
. J’utilise pour ce faire la fonction Add Revision Label…
de MacHg qui me permet (entre autres) de faire cela. J’indique alors le nom de cette nouvelle branche dans l’onglet idoine. MacHg m’indique que ce label, cette branche, sera affectée à la révision qui sera commitée la prochaine fois :
Les commandes terminal correspondante sont les suivantes[1] :
hg branch config hg update config
Une fois cette création de branche validée, je crée un nouveau fichier _config.php
utile pour cette fonctionnalité nouvelle et je modifie la version de mon développement dans le fichier _define.php
. On peut constater le résultat sur la liste des fichiers du répertoire de travail :
Un nouveau fichier a été détecté par MacHg ainsi qu’une modification d’un des fichiers existant. J’ajoute le nouveau fichier à l’aide de la commande AddRemove Selected File…
pour inclure la gestion de ce nouveau fichier dans le dépôt Mercurial :
La commande équivalente est la suivante :
hg add _config.php
Enfin j’enregistre ces modifications à l’aide de la commande commit que désormais vous devriez bien connaître. Vous remarquerez que sur la boîte de dialogue ouverte pour effectuer cet enregistrement MacHg m’indique que je travaille sur la branche config
:
La commande correspondante est :
hg commit -m 'nouvelle branche config
Je valide l’enregistrement et j’affiche la liste des révisions présentes dans mon dépôt :
Vous pouvez constater la présence d’une révision 3
affublée du label de la branche default
et d’une nouvelle révision 4
correspondant à la nouvelle branche config
. Mon répertoire de travail est pour l’instant celui correspondant à cette dernière branche. Vous y trouvez le fichier _config.php
nouvellement créé :
Je peux continuer autant que nécessaire à modifier le contenu de mon répertoire de travail et enregistrer (via commit) mon travail. Cela se fera toujours sur cette branche config
.
Imaginons maintenant que je veuille poursuivre le travail sur la branche normale, celle où je n’ai pas ajouté cette nouvelle fonctionnalité matérialisée par le fichier _config.php
. Pour cela il va falloir que je demande à MacHg de me ramener dans l’état où j’étais avant de créer la nouvelle branche. J’utilise la commande Update
présente sur la barre d’outils de MacHg qui m’affiche alors la fenêtre suivante :
Commande équivalente :
hg update default
L’état courant du répertoire de travail est représenté par la ligne surlignée en violet pale. J’ai sélectionné la révision 3
, surlignée en vert, celle qui possède le label default
et je valide. Une fois l’opération effectuée j’obtiens le message suivant :
Il y a eu 1 fichier mis à jour — le fichier _define.php
— et 1 fichier enlevé — le fichier _config.php
. J’ai alors récupéré mon répertoire de travail dans l’état dans lequel il était avant la création de la nouvelle branche :
Je vais maintenant continuer mes modifications, en ignorant ce qui a été fait sur la branche config
qui reste enregistrée et au chaud dans mon dépôt. Je modifie par exemple un des fichiers, comme indiqué par MacHg sur la liste des fichiers de mon répertoire :
Je vais maintenant enregistrer ces modifications, toujours avec un commit
et MacHg m’indique cette fois que je vais bien enregistrer cette révision sur la branche default
:
Commande équivalente :
hg commit -m 'Suite version standard'
Vous pouvez constater maintenant que les deux branches, default
et config
ont commencé à diverger :
Je peux ainsi basculer de l’une des branches vers l’autre, continuer à développer, à faire des commit, en étant sûr de ne pas interférer dans les développements de l’autre branche. C’est ce que je fais maintenant en retournant sur la branche config
, à l’aide de la commande update
. Mon répertoire de travail sera restauré dans l’état dans lequel il était lors de l’enregistrement de la révision 4
:
Commande équivalente :
hg update config
Je modifie à nouveau un ou plusieurs fichiers de cette branche et j’enregistre avec un commit cette nouvelle révision :
Etc, etc.
Conclusion
Vous devriez avoir compris maintenant comment travailler sur plusieurs voies de développement — certains appellent ces voies des versions — quel que soit d’ailleurs le nombre de contributeurs. Ce qui est valable ici localement l’est tout autant sur un dépôt distant.
Nous verrons dans la leçon suivante comment réunir tout ou partie d’une branche dans une autre et comment résoudre les conflits qui peuvent se présenter lorsque par exemple le même fichier a été modifié dans les deux branches.
Glossaire
branch : Ensemble indépendant de révisions d’un dépôt. Une branche peut être créée, fermée, fusionnée (merge) avec une autre.
Pour en savoir plus
- Un guide un peu plus avancé sur la gestion des branches avec Mercurial
Notes
[1] Je ne suis pas sûr et certain que la deuxième commande soit utile dans le cas présent. Quoi qu’il en soit elle n’aura aucun effet indésirable ici.
1 De [SiMON] -
Pour la note de bas de page, un man hg indique pour la commande branch que
, il ne doit donc pas être nécessaire d’exécuter un hg update derrière effectivement.En tout cas, merci pour ces explications, ça et la suite, je vais enfin commencer à comprendre des trucs qui m’échappaient quelque peu :) !
2 De Franck -
Merci [SiMON], ça fait plaisir de lire qu’au moins un lecteur y comprend quelque chose !
Cela dit il ne me reste plus grand chose à expliquer, à part le merge et la résolution de conflits — ce sera l’objet de la prochaine leçon — et quoi faire en cas de catastrophe — ce qui sera l’objet de la leçon suivante. Ensuite je vais me reposer un peu parce que les tutos, ça consomme pas mal de jus de cerveau, je trouve ;-)
3 De mirovinben -
Je bute sur “il va falloir que je demande à MacHg de me ramener dans l’état où j’étais avant de créer la nouvelle branche”. Gloups… J’aurais imaginé que toute modif sur “config” n’impactait en rien “default” qui ne changeait pas et n’avait pas besoin d’un update.
Bon, faut que je relise plusieurs fois tout ça posément… Voir faire des tests en local.
En tout cas, bravo pour tout ce jus de cerveau versé à notre profit.
4 De Franck -
mirovinben il faut comprendre qu’il n’y a qu’un seul répertoire de travail et qu’il ne reflète qu’une branche à la fois (voire même qu’une seule révision).
Donc en fonction de tes besoins, tu switches d’une branche à l’autre pour pouvoir y apporter des modifications.
Pour résumer, chaque branche est indépendante dans le dépôt, le répertoire de travail est partagé pour effectuer les développements.
5 De Franck -
Cela dit, on peut aussi imaginer d’avoir 2 répertoires de travail, représentant chacun une branche. Dans ce cas plus besoin d’update pour basculer de l’un à l’autre puisque les dossiers sont séparés. Par contre, cela ne peut se faire qu’avec un dépôt distant puisqu’en local le dépôt (et tout son historique) est stocké à la base du répertoire de travail (dossiers
.hg
…)C’est ainsi que je teste les différentes branches actuelles de Dotclear (
2.3
,default
qui deviendra la future2.4
et une branchetheme
sur laquelle nous travaillons avec Kozlika pour le développement du thème Ductile).6 De [SiMON] -
En farfouillant dans la documentation de BitBucket, j’en suis arrivé à trouver A Guide to Branching in Mercurial, qui récapitule les différentes manières de gérer des branches (via les
branches
en tant que telles, le système debookmarks
et le système deforks
).On pourra y glaner plusieurs informations intéressantes qui compléteront idéalement ce tutoriel.
7 De Franck -
Merci pour le lien !