Git protip : renommer un vieux commit
Par Maxime Bréhin • Publié le 17 octobre 2022
• 3 min
Tout comme il m’arrive d’oublier des fichiers dans un commit, il m’arrive également de mal rédiger des messages de commit et de m’en apercevoir plus tard (avec quelques commits effectués entre temps). Ce que j’oublie probablement le plus souvent, c’est lier le ticket traité par le commit.
PLUS tard, pas TROP tard !
Ne me dis pas que tu penses « Tant pis, j’irai dans l’interface le renseigner à la main ! » ou que tu laisses tomber ! C’est peut-être parce que tu ne connais pas le rebase interactif, ou que tu en as peur 😨. Franchement, tu ne devrais pas, avec un peu d’apprentissage cette commande s’avère être une alliée plus que précieuse !
Mis à part cette histoire de rebase, sais-tu qu’on a la possibilité de créer un commit qui exprime cette intention de changer le message ? Je parie que non ! Heureusement, je suis là 😁. Je te présente la commande git commit --fixup reword:<ref-du-commit-à-corriger>
. Alors oui, cette syntaxe n’est pas facile à retenir. Mais on s’en moque, on va se faire un bel alias aux airs d’incantation magique 🔮. Introducing autoreword :
git config --global alias.autoreword '!git commit --fixup reword:$1 && GIT_EDITOR=true && git rebase --autosquash --interactive --rebase-merges $1~1 && echo "autoreword finished"'
Que va-t-il se passer si tu lances cette commande ?
🌀 Un vortex maléfique s’ouvrira, libérant les flammes de l’enfer qui réduiront ce monde en cendres 🔥 !! (En fait non, pas besoin de magie pour ça 😭)
Plus sérieusement, Git va ouvrir ton éditeur avec un message démarrant par amend! …
suivi de la première ligne du message du commit à corriger, puis un saut de ligne et à nouveau le message du commit à corriger (complet cette fois, donc potentiellement sur plusieurs lignes).
amend! chore(dx): setup ESLint and Prettier
chore(dx): setup ESLint and Prettier
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch chore/automation
Tu peux alors changer tout le message, sauf la première ligne.
amend! chore(dx): setup ESLint and Prettier
chore(dx): setup ESLint and Prettier
# J’ajoute la fermeture du ticket associé
# dans mon outil de gestion de projet
Closes #42
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch chore/automation
Reste à enregistrer puis fermer.
Git finalise alors la création du commit signalant la correction, puis notre alias lance automatiquement le rebase interactif en partant du commit précédent le commit à corriger. Et comme on a précisé juste avant dans l’alias GIT_EDITOR=true
, il n’ouvre pas l’éditeur et auto-valide le rebase interactif.
Là on est carrément dans de la magie noire ! Soyons donc un peu curieux et regardons ce qu’il effectue si on retire ce GIT_EDITOR=true
de l’alias : il ouvre à nouveau ton éditeur avec la liste des actions qu’il s’apprête à mener. Et là, surprise : ton commit signalant la correction est automatiquement placé sous le commit à corriger avec le préfixe fixup -C
.
pick 3f0714b chore(dx): setup ESLint and Prettier
fixup -C 61eecda amend! chore(dx): setup ESLint and Prettier
pick 9a7cf39 chore(dx): setup Husky, lint-staged, precommit-checks, commitlint
Tu n’aurais rien d’autre à faire qu’à vérifier, enregistrer et fermer le fichier. Ton rebase entre ensuite en action (sans conflit).
Dans tous les cas tu vérifieras ton log pour voir que tout est bon !
Si tu vois dans le fichier décrivant les actions du rebase les clés label onto
et reset onto
c’est normal, c’est lié à l’option --rebase-merges
qui garantit la préservation de tes fusions locales lors du rebase. Tu n’as pas à t’en préoccuper 😌.