Super squash Git

Une technique sympa pour travailler avec des branches bavardes sur Git.

Un petit article sympa pour vous montrer un workflow particulier que j’ai récemment adopté avec Git qui se sert des squashs de commits pour garder un historique Git propre.

Prélude

Je vais ici vous présenter un exemple où le squash s’applique très bien : la rédaction des articles sur ce blog.

J’ai pour (mauvaise) habitude de me lancer dans la rédaction d’articles pour celui-ci en parallèle. Afin de pouvoir travailler sur tel ou tel article en fonction de mon humeur et de l’alignement des 3 lunes, j’utilise donc des branches pour gérer chaque article séparément (si vous utilisez Git mais ne vous servez pas des branches, vous ratez vraiment quelque-chose, alors mieux vaut tard que jamais).

Dès qu’un article est terminé, je peux donc merger (fusionner pour les anglophobes ou francophiles) la branche avec mon article dans master, la branche principale.

Cependant, j’ai pu me rendre compte avec le temps que cette méthode « polluait » l’historique Git du dépôt.

En effet, vu que je travaille sur les articles de manière asynchrone, on trouve dans l’historique de la branche de travail sur l’article en question de nombreux commits aux descriptions et contenus divers :

  • « Premier rush »
  • « Second rush »
  • « Typo »
  • « Oubli »
  • Et autres commits aux messages aussi bien détaillés…

Et donc lorsque l’on fusionne cette branche dans master on se retrouve avec tout ce bruit dans l’historique Git, alors que l’on pourrait (devrait) avoir un seul commit final contenant un message du genre « Ajout d’un nouvel article sur l’automatisation ».

Plus le projet avance et plus les messages de commit sont confus…

Le but est de rassembler un ensemble de petits commits peu intéressants en un seul joli / CC-BY-NC xkcd

Git squash à la rescousse

C’est donc ici qu’intervient le Git Squash !

C’est quoi un squash ?

Squash, que l’on peut traduire par « aplatir », porte bien son nom. Son rôle est simple : fusionner plein de commits dans un seul. Les utilisations de cette méthode peuvent être nombreuses et n’ont de limite que votre imagination.

On va donc pouvoir s’en servir ici afin de fusionner tous nos commits d’avancement sur l’article en un seul gros commit sur master avec la commande suivante :

$ git checkout master
$ git merge --squash mabranche

Cette opération va donc rejouer toutes les modifications apportées dans la branche mabranche sur master, mais sans effectuer aucun commit ni merge dessus.

Vous n’avez plus qu’à faire un commit avec un joli message qui décrit l’ensemble du travail que vous avez pu effectuer sur cette branche.

Du fait que cette méthode ne travaille pas avec les branches, lorsque vous allez vouloir supprimer la branche Git va vous indiquer (à raison) que vous n’avez pas fusionné les commits de la branche dans master (car en effet on ne les a pas fusionnés, mais on a rejoué toutes les modifications qu’ils comportaient afin d’en faire un beau et gros commit propre).

Il faudra donc vous assurer de bien avoir manuellement fusionné les changements dans master avec la technique du squash avant de forcer la suppression de cette branche avec git branch -D mabranche.

Démo

Voici une petite démonstration rapide pour vous montrer un squash entre différents commits bidons.

Conclusion

Je vous recommande cette méthode de travail si vous avez tendance à faire plein de petits commits sur une branche et que vous voulez que seul le gros changement que vous avez fait soit enregistré sur master, ce qui s’applique très bien aux articles de ce blog par exemple.

Une question ou remarque ? N'hésitez pas à me contacter en envoyant un mail à microjoe, suivi d'un arobase, puis encore microjoe et enfin un « point org ».