Quand faut-il « squash merge » ?
Il y a trois ans, nous avons « squash merge » une énorme fonctionnalité qui avait représenté plus d’un an de développement et l’intervention de près d’une dizaine de personnes. Aujourd’hui encore, nous nous en mordons les doigts, c’est ce qui m’amène à vous partager cet article : que cela ne se reproduise plus !
Si vous avez déjà créé une Pull Request (PR) sur GitHub (ou une Merge Request sur Gitlab), vous connaissez ce bouton :
Nous avons plusieurs options de merge afin de récupérer les modifications de la PR sur la branche de référence :
- ajouter tous les commits de la PR avec un commit de merge en cliquant sur le bouton Create a merge commit ;
- ajouter individuellement les commits sans commit de merge et réécrire l’historique au dessus avec le bouton Rebase and merge ;
- fusionner tous les commits en un seul avec le bouton Squash and merge.
Nous allons voir dans cet article dans quel cas il est judicieux ou au contraire totalement non indiqué de cliquer sur ce dernier.
Section intitulée quand-faire-un-squash-mergeQuand faire un squash merge
La question principale à se poser est : voulons-nous réécrire l’historique ?
Section intitulée je-suis-seule-sur-ma-brancheJe suis seule sur ma branche
- Ma PR comporte une seule fonctionnalité et plusieurs commits dont des « fix review », « fix tests », « oops »… ⇒ un squash merge sera apprécié. En effet, avoir des commits avec uniquement du code d’un bout de fonctionnalité n’apporte rien, si nous regardons un de ces commits individuellement nous ne comprendrons pas forcément le code car nous n’avons plus le contexte. En faisant un squash merge, l’historique reste propre et le code associé à la fonctionnalité est regroupé dans un seul commit, ce qui facilite le débogage futur de celle-ci ;
- Ma PR comporte une seule fonctionnalité, plusieurs commits qui ont chacun leur importance avec un message de commit clair ⇒ l’historique de commits me convient, je fais un commit de merge ;
- Ma PR comporte plusieurs fonctionnalités ⇒ je fais plusieurs PRs 😛
Section intitulée nous-sommes-plusieurs-sur-la-brancheNous sommes plusieurs sur la branche
Il arrive que nous puissions être plusieurs sur une même branche, il peut s’agir d’une très grosse fonctionnalité qui comprend des aspects d’intégration, de développement front, et de développement back par exemple. Ce que nous conseillons dans ce cas :
- Créer la branche principale/epic dédiée à la fonctionnalité, que nous appelons ici
feature/ticket_big_feature
; - Chacun des intervenants pousse son code dans une branche basée sur
feature/ticket_big_feature
, et donc pour chacune de ces PRs nous reprenons la partie « Je suis seule sur ma branche » ; - Merge final avec un commit de merge de la PR de la branche
feature/ticket_big_feature
.
Ici nous déconseillons fortement de faire un squash merge de cette grosse PR, car :
- La personne qui va squash et merge la PR s’approprie le code écrit par les copains, c’est pas joli joli.
Ex. :
— Oh Jean-Mi je savais pas que tu faisais de l’intégration, c’est super cool ce que t’as fait dans le fichierfile.scss
.
— Non c’est pas moi, j’ai squash-merge.
— Ah.
- Nous ne savons pas qui a écrit le code, nous ne savons pas à qui poser nos questions, et retrouver la personne concernée prend beaucoup plus de temps.
Ex. :
— Hey Melissa, dans le fichierfile.php
pourquoi t’as fait une fonction machin au lieu de truc ?
[Melissa ouvre le fichier, se remémore le sujet et…]
— Ah ce n’est pas moi qui ait écrit ce code, j’ai squash merge, regarde sur la PR.
[Linh cherche le hash du commit, l’affiche dans github, retrouve la PR]
— Il y a 45 commits et 430 fichiers modifiés 😰 (Oui, grosse feature on a dit 😜), ça va être compliqué ;
- Lire des petits commits est plus lisible qu’un gros commit ;
- Git-bisect (Outil permettant de trouver le commit ayant introduit un bug) fonctionne mieux avec des petits commits.
Section intitulée tout-seul-sur-le-projetTout seul sur le projet
Dans un projet où vous êtes le seul à travailler, c’est super d’utiliser un logiciel de gestion de versions, bravo 👏.
Vous seul verrez l’historique, mais ça peut toujours servir d’utiliser des branches et de squash / merge au besoin et votre vous du futur vous remerciera d’avoir maintenu un historique git propre.
Section intitulée a-savoirÀ savoir
- Si vous venez de faire un commit mais vous vous rendez compte que vous avez oublié un bout de code, hop un
$ git commit --amend
pour rajouter ces dernières modifications au commit précédent fera l’affaire (si le commit était déjà push, ne pas oublier de push en--force-with-lease
pour ne pas risquer d’écraser le code d’un copain) ; - Autre possibilité de réécriture d’historique :
$ git rebase -i HEAD~3
Cette commande va vous permettre de modifier les 3 derniers commits de votre branche en choisissant quel commit vous voulez garder, squash, supprimer, etc.
pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
Utile quand vous avez dans une PR des commits que vous souhaitez garder tels quels et d’autres que vous souhaitez fusionner. Plus d’infos dans le git book.
Quitte à avoir un historique propre, autant qu’il soit bien structuré 😊. J’en profite ici pour vous parler des Commits conventionnels, il s’agit d’une spécification sur les messages de commits permettant une meilleure visibilité de ce que fait un commit.
Nous avons dans cette spécification, entre autres, l’ajout d’un préfixe à chaque message de commit tel que feat
pour l’ajout d’une feature, fix
pour la correction d’un bogue, ou encore docs
pour l’ajout de documentation. En parlant de documentation, je vous invite à regarder celle du site, tout y est très bien expliqué et disponible en plusieurs langues.
Section intitulée conclusionConclusion
L’historique de commits n’est pas anodin et peut avoir des conséquences sur les prochains debugs ; essayons de nous faciliter la tâche 😊.
Commentaires et discussions
Nos formations sur ce sujet
Notre expertise est aussi disponible sous forme de formations professionnelles !
Git
Historisez vos développements avec l’outil de gestion de version Git