Le Squashing de commits sur GitLab : Nettoyer son historique
C'est quoi le Squashing et pourquoi l'utiliser ?
Au cours du développement d'une fonctionnalité, il est normal de faire plusieurs petits enregistrements (commits). Parfois, ces commits servent juste à corriger une petite faute de frappe ou à faire un test rapide. Si vous envoyez tout cela tel quel sur la plateforme, l'historique du projet GitLab va devenir très long et difficile à lire pour vos collègues.
Le Squashing de commits (ou écrasement) est une technique qui permet de fusionner plusieurs commits en un seul. Imaginez que vous écrivez un rapport : vous faites dix brouillons avec des ratures partout. Avant de le rendre à votre responsable, vous regroupez tout en une seule version propre. Pour Git, c'est la même chose : on transforme une série de petits changements brouillons en une modification propre et professionnelle.
Préparer le terrain pour le Squash
Pour pratiquer, nous allons créer une situation où nous avons plusieurs commits inutiles à regrouper au sein de votre dépôt.
Création d'une branche de travail
Créez une branche nommée squash-chapter pour faire vos tests de fusion :
git switch -c squash-chapter
Faire plusieurs petits commits
Nous allons créer un fichier et effectuer deux modifications séparées pour simuler un historique chargé :
echo "Ligne 1" > mon_code.txt
git add mon_code.txt
git commit -m "Premier ajout"
echo "Ligne 2" >> mon_code.txt
git add mon_code.txt
git commit -m "Deuxième ajout avec une correction"
Si vous regardez votre historique avec la commande git log --oneline, vous verrez deux lignes. L'objectif est de simplifier l'historique Git pour n'en avoir plus qu'une seule.
Réaliser le Squashing avec le Rebase Interactif
Pour fusionner ces commits, nous allons utiliser une variante puissante du rebase : le mode interactif de Git.
Lancer la commande de fusion
Nous voulons regrouper les 2 derniers commits. Tapez la commande suivante dans votre terminal :
git rebase -i HEAD~2
Note technique : Le symbole ~2 indique à Git de remonter de deux crans dans l'historique. Si vous aviez 5 commits à regrouper, vous utiliseriez ~5.
Utiliser l'éditeur de texte (Vim ou Nano)
Un éditeur de texte s'ouvre alors. Vous verrez vos deux commits précédés du mot pick.
Interface de l'éditeur :
pick a1b2c3d Premier ajout
pick e4f5g6h Deuxième ajout avec une correction
# Rebase ...
# Commands:
# p, pick = use commit
# s, squash = use commit, but meld into previous commit
Pour fusionner les commits, vous devez remplacer le mot pick de la deuxième ligne par squash (ou juste la lettre s). Cela signifie littéralement : "Prends ce commit et écrase-le dans le précédent".
Sauvegardez et quittez (sur Vim, appuyez sur Echap, tapez :wq puis Entrée). Git vous demandera ensuite de rédiger un message de commit final pour l'ensemble.
Envoyer le résultat sur GitLab
Puisque vous avez réécrit l'histoire de votre branche, un simple push classique sera systématiquement refusé par le serveur.
Le push forcé (Force Push)
Si le serveur refuse l'envoi, vous devrez utiliser l'option --force. Attention, c'est une commande à utiliser avec prudence et uniquement sur vos propres branches de travail :
git push origin squash-chapter --force
Conclusion
Le Squashing est une excellente habitude à prendre avant de soumettre une Merge Request sur GitLab. Cela prouve que vous êtes un développeur organisé qui accorde de l'importance à la propreté du code source.
Maintenant que vous gérez votre code comme un pro, il est temps d'apprendre à gérer les accès. Dans le chapitre suivant, nous verrons comment ajouter des utilisateurs à un projet GitLab pour collaborer efficacement.
Espace commentaire
Écrire un commentaire
Rejoignez la discussion
Vous devez être connecté pour poster un message.
24 commentaires
Si vous avez d'autres galères avec le rebase, postez votre log. N'oubliez pas que l'historique est une ressource partagée, soyez propres.
Si, c'est pour ça qu'on privilégie
git push --force-with-lease. Ça vérifie que personne n'a poussé de nouveaux commits avant de forcer. C'est beaucoup plus safe.Le
git push --force, c'est pas risqué pour les collègues ?Pas de panique, Git garde tout. Tape
git reflog, trouve le hash de ton commit avant le rebase, et fais ungit reset --hard [hash]pour tout récupérer.J'ai perdu un commit en faisant une fausse manip pendant le rebase, je suis dégoûté.
Oui, utilise
fixupau lieu desquashdans l'éditeur interactif si tu veux jeter les messages, ou reste sursquashpour les garder et les éditer.Est-ce que je peux squasher en gardant les messages des commits fusionnés ?
Ça arrive si ton
HEADn'est pas bien défini ou si t'es en état de detached HEAD. Vérifie sur quelle branche tu es avecgit branch.J'ai une erreur 'invalid upstream' quand je lance la commande. C'est quoi ce délire ?
Merci pour le guide. J'ai enfin une MR propre sur GitLab, ça fait plaisir de ne plus voir mes 15 commits 'wip'.
À ne jamais faire si d'autres gens travaillent sur la même branche. Tu vas casser l'historique de tout le monde. Réservé aux branches de feature perso uniquement.
Est-ce qu'on peut squasher des commits qui ont déjà été poussés sur la branche distante commune ?
Surtout pas. Git te donne la main pour résoudre. Une fois le fichier corrigé, fais :
J'ai un conflit de fusion pendant mon rebase. Je fais quoi ? Je panique ?
Le
merge --squashc'est pour l'intégration finale. Le rebase interactif, c'est pour nettoyer ton propre historique avant de montrer ton code. C'est deux usages différents.Question bête : pourquoi on ne fait pas juste un
git merge --squashà la fin plutôt que de faire un rebase interactif sur la branche ?Oui, utilise
git reset --soft HEAD@{1}pour annuler le dernier commit tout en gardant tes modifs en staging. Tu pourras recommencer ton commit propre.Le squash, c'est bien, mais si je me plante dans le message de commit final, je peux revenir en arrière ?
C'est normal. Si ta branche est protégée, le force push est bloqué par défaut dans les réglages du projet. Va dans Paramètres > Dépôt > Branches protégées pour autoriser le force push sur ta branche.
J'ai fait un
git push --forcemais GitLab me jette toujours. Il me dit que la branche est protégée. Une idée ?Carrément. Passe cette commande dans ton terminal :
git config --global core.editor nano. Plus besoin de galérer avec les modes de Vim.Perso, Vim me rend fou. Je peux changer l'éditeur par défaut pour utiliser Nano avec le rebase ?
T'as sûrement mal compté. Si t'as fait 3 commits, faut taper
git rebase -i HEAD~3. Vérifie toujours ton log avant avecgit log --oneline.Tuto utile mais j'ai une erreur au moment du
git rebase -i HEAD~2. Git me dit qu'il ne trouve pas de commits à éditer alors que j'en ai bien fait trois.