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
Il arrive dans certains cas que nous ayons besoin de récupérer les modifications effectuées sur un ou plusieurs fichiers pour les reporter sur une autre branche, sur un autre dépôt sur lequel nous n’aurions pas le droit de soumettre, etc. Dans ce cas il existe une fonction qui permet d’exporter sous forme textuelle ce qui a été modifié. Ce fichier texte — nommé patch — est ensuite utilisé pour importer les modifications.
Création d’un patch
Imaginons que je fasse quelques modifications sur le fichier _public.php
qui contient au préalable ceci :
<?php … class tplDuctileTheme { public static function publicHeadContent($core) { echo '<style type="text/css">'."\n". 'h1 { font-size: 2em; }'."\n". 'h2 { font-size: 1.8em; }'."\n". 'a { color: #F00; }'."\n". "</style>\n"; echo '<link href="images/favicon.png" type="image/png" rel="icon">'; } } ?>
Pour obtenir finalement cela :
<?php … class tplDuctileTheme { public static function publicHeadContent($core) { echo '<style type="text/css">'."\n". 'h1 { font-size: 2.4em; }'."\n". 'h2 { font-size: 2em; }'."\n". 'h3 { font-size: 1.6em; }'."\n". 'a { color: #F00; }'."\n". "</style>\n"; echo '<link href="images/favicon.png" type="image/png" rel="icon">'; } } ?>
Si je veux récupérer ces modifications pour pouvoir les appliquer ailleurs (sur une autre branche, sur un autre dépôt, …) je vais alors utiliser la commande Export Patches…
de MacHg. Les modifications n’étant pas encore commitées, je sélectionne la future
révision (voir la copie d’écran ci-dessous) et je valide en cliquant sur le bouton Export
:
Si j’ouvre le fichier résultant j’obtiens cela :
diff --git a/_public.php b/_public.php --- a/_public.php +++ b/_public.php @@ -20,8 +20,9 @@ { echo '<style type="text/css">'."\n". - 'h1 { font-size: 2em; }'."\n". - 'h2 { font-size: 1.8em; }'."\n". + 'h1 { font-size: 2.4em; }'."\n". + 'h2 { font-size: 2em; }'."\n". + 'h3 { font-size: 1.6em; }'."\n". 'a { color: #F00; }'."\n". "</style>\n"; echo '<link href="images/favicon.png" type="image/png" rel="icon">';
Ceci est la forme standardisée d’un patch qui indique le nom du fichier en question, les lignes impactées (précédées du signe -
pour les suppressions, du signe +
pour les ajouts) et les quelques lignes qui précèdent et qui suivent.
Ce fichier peut ensuite être utilisé pour appliquer ces modifications sur une autre branche ou un autre dépôt.
Utilisation d’un patch
Imaginons maintenant que j’ai une autre branche dans laquelle je souhaite reporter les modifications exportées au chapitre précédent. Je vais dans ce cas utiliser la commande Import Patches…
de MacHg.
J’inclus alors le patch précédemment exporté en sélectionnant le fichier à l’aide du bouton +
. MacHg m’indique alors visuellement le contenu du patch et me permet au passage d’effectuer un commit, ce que je ne vais pas faire. Il suffit pour cela de décocher la case correspondante. Vous observerez que vous pouvez inclure plusieurs patchs à appliquer dans la même opération, ce que d’habitude j’évite de faire, préférant contrôler tout ça pas à pas :
Je lance l’opération en cliquant sur le bouton Import
et MacHg applique alors le contenu du patch sur mon répertoire de travail, en l’occurrence sur le fichier _public.php
. Il ne me reste plus qu’à commiter (rappelez-vous que j’avais décoché la case idoine sur la fenêtre d’importation de patch) pour enregistrer cette nouvelle révision.
Cela dit l’usage d’un patch est limité parce qu’il impose un état de départ et un état d’arrivée du ou des fichiers impactés et parfois il sera impossible d’appliquer le patch, les fichiers correspondants ayant été modifiés depuis. Ce système peut donc rendre service mais sachez qu’il a une limite vite atteinte.
Collaboration indirecte
Le service Bitbucket inclut une fonctionnalité de pull request qui permet à une personne ayant forké un dépôt de proposer une évolution. Par exemple, sur le dépôt distant et stocké chez Bitbucket et qui m’a servi à illustrer cette série de leçons, une certaine Kozlika m’a fait un pull request.
Pour y arriver elle a effectué les opérations suivantes :
- Fork de mon dépôt intitulé « Commun » sur son compte Bitbucket
- Clone sur son ordinateur de son dépôt distant « Commun »
- Modification d’un ou plusieurs fichiers
- Commit pour enregistrer une ou plusieurs révisions
- Push pour enregistrer localement et sur le dépôt Bitbucket les révisions
Ensuite elle a utilisé la fonction de création de pull request disponible sur le site et qui permet d’indiquer si nécessaire les branches concernées, un titre et un commentaire sur le contenu des révisions proposées.
Je peux ensuite consulter le détail de sa proposition sur une nouvelle page du site avec entre autres le détail au format diff (le même que celui utilisé pour les patchs, voir le début de cette leçon) des modifications. Je peux alors accepter celles-ci ou les rejeter :
Je décide alors d’accepter et un push est alors effectué sur mon dépôt avec ces modifications. Je peux ensuite récupérer celles-ci sur mon dépôt local avec un pull suivi d’un update pour mettre à jour mon répertoire de travail. Voilà désormais l’état de mon dépôt :
Notez au passage que Bitbucket vous informera par mail du résultat de chacune de ces opérations (création de pull request, acceptation ou refus, …).
Conclusion
Vous savez maintenant comment effectuer des modifications indirectes (sur d’autres branches, sur d’autres dépôts) à l’aide de patchs. Vous savez désormais comment utiliser le service de pull request chez Bitbucket pour proposer à d’autres vos développements à partir d’un dépôt que vous aurez forké.
Glossaire
patch : fichier au format unifié spécifiant les modifications apportées à un ou plusieurs fichiers.
pull request : système de collaboration permettant de transmettre une révision d’un dépôt forké au propriétaire du dépôt original, ce dernier restant libre d’accepter ou non votre proposition.
Postface
Cette leçon sera la dernière de cette série et j’espère qu’elle vous aura permis d’appréhender sans trop de difficultés ce qu’est une gestion de révisions, de découvrir ses avantages et ses contraintes.
Pour ma part, et après quelques semaines d’utilisation de Mercurial, j’ai compris qu’il valait mieux commiter souvent de petites modifications plutôt que des grands ensembles, qu’il valait mieux créer des petites branches, quitte à les multiplier, plutôt que de travailler sur une seule branche où les retours en arrière peuvent être compliqués.
N’hésitez surtout pas à vous créer des dépôts factices pour tester et retester toutes les commandes et les autres dont je n’ai pas parlé jusqu’alors. Ça ne coûte qu’un peu de temps et d’espace disque. C’est d’ailleurs ce que j’ai fait pour découvrir petit à petit toutes les possibilités offertes par ce système et j’ai d’ailleurs conçu ce tutoriel comme un aide-mémoire pour les jours lointains où j’en aurai probablement oublié la moitié.
Merci d’avoir lu jusqu’ici !
1 De mirovinben -
Merci pour ce didacticiel… Un pas à pas fort bien expliqué. Du moins il me semble… Je n’ai pas tout compris car je n’ai fait que lire sans passer à la pratique. Faut donc que je m’y mette. Peut être avec un de mes plugins en attendant d’oser pusher, forker, cloner, commiter sur toutes les branches de DC en direct-live.
Héhé… Je vois la panique t’envahir, la sueur couler le long de tes tempes et comme un regret d’avoir si bien détaillé les choses. Trop tard. :-)
2 De Franck -
Hé hé, au contraire je jubilerais de te voir commiter et pusher un jour quelque chose sur une des branches. Tu ne voudrais pas essayer, ne serait-ce que pour corriger une coquille ou que sais-je encore ?
3 De adjaya -
Merci pour le didacticiel, super travail!, qui m’a aidé à faire mes premier pas dans l’univers de Mercurial. J’ai un peu ramé par rapport à tes explications car je suis sous un autre os, mais j’ai fini par réussir à faire les principales opérations décrites ici. j’ai même pu créer un clone de dotclear en provenance du site bitbucket, crée un compte chez eux et synchronisé en local. je crois que je vais adopter ce support de dev. pour mes projets, et peut être finir par sortir de mes méthodes préhistoriques, que j’aime bien pourtant aussi :).
4 De Franck -
Ravi, adjaya, que ça ait pu t’aider à démarrer avec Mercurial.
5 De Loïc -
Merci Franck pour cette série d’articles ! Fort utile d’avoir un dépôt pour gérer mes fichiers de configuration de mon OS et de mes outils habituels sur différentes machines.
6 De Franck -
Tant mieux Loïc !
7 De JcDenis -
Au fait, merci pour ce tuto, c’est ma bible et mon pense bête.
Sans ça j’aurai abandonner mes coup de main à Dotclear !
8 De Franck -
Zizir™ JcDenis ;-)
9 De Thierry -
Très joli tuto pas à pas grâce auquel j’ai fait plus que découvrir Mercurial et bitbucket. Agréable à lire, clair et détaillé à la fois, il restera en favori comme aide-mémoire.
Merci Franck.
10 De Franck -
You’re welcome Thierry.
11 De cavo789 -
J’ai galéré hier pendant deux heures; probablement trois pour faire fonctionner Mercurial avec mon éditeur NetBeans et, non, rien à faire. Je parvenais au mieux à faire un commit en local mais rien du tout sur le serveur. web.
J’ai lu toute votre série d’article ce matin dans le train et je vais maintenant recommencer en pratiquant en même temps.
D’ores et déjà, merci pour votre travail de rédaction afin de mettre hg à la portée de tous.
Merci.