Mercurial pour nous les nuls, leçon 11 : patch, pull request

L’index des leçons :

  1. Leçon 1 : la gestion de version
  2. Leçon 2 : qu’est-ce qu’un dépôt ?
  3. Leçon 3 : les logiciels ”clients”
  4. Leçon 4 : création d’un dépôt
  5. Leçon 5 : enregistrement de révision
  6. Leçon 6 : synchronisation de dépôts, mise à jour du répertoire de travail
  7. Leçon 7 : identifier les différences
  8. Leçon 8 : la gestion des branches
  9. Leçon 9 : la fusion de branche
  10. Leçon 10 : retour vers le passé
  11. 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 :

Fenêtre de sélection et d'export de patch

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 :

Importation d'un patch

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.

Liste des pull requests

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 :

Actions possibles sur un pull request

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 :

État des révisions après le pull request accepté

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 !

Ajouter un commentaire

Les champs suivis d'un * sont obligatoires

Les commentaires peuvent être formatés en utilisant la syntaxe Markdown Extra.

Ajouter un rétrolien

URL de rétrolien : https://open-time.net/trackback/7135

Haut de page