git rebase -i (interactif)
Apprenez le rebase interactif avec git rebase -i pour squasher, renommer, modifier et réorganiser vos commits avant de les partager.
Qu'est-ce que le rebase interactif
Le rebase interactif, lancé avec git rebase -i, vous permet de réécrire une série de commits avant de les partager. Il ouvre une "liste de tâches" modifiable où vous décidez, ligne par ligne, ce qui arrive à chaque commit — le conserver, réécrire son message, le fusionner dans un autre, le diviser, le réorganiser ou le supprimer. Il s'appuie sur le git rebase classique, mais vous donne le contrôle sur chaque étape.
Cette page explique comment démarrer un rebase interactif, toutes les commandes disponibles dans la liste de tâches, les workflows les plus courants (squash, réécriture de message, réorganisation, suppression et division de commits), comment récupérer en cas de problème, et la règle essentielle pour l'utiliser en toute sécurité.
Un commit est un instantané sauvegardé de votre travail ; HEAD est un pointeur vers le commit sur lequel vous vous trouvez actuellement. "Réécrire l'historique" signifie produire de nouveaux commits pour remplacer les existants — Git ne modifie jamais un commit en place, donc chaque commit réécrit reçoit un hash entièrement nouveau.
Démarrer un rebase interactif
Pointez la commande sur le commit précédant le premier que vous souhaitez modifier — le rebase rejouera tout ce qui vient après. Pour retravailler les trois derniers commits :
git rebase -i HEAD~3HEAD~3 signifie "trois commits en arrière depuis HEAD". Vous pouvez aussi indiquer un commit explicite (git rebase -i a1b2c3d) ou, sur une branche, rebaser tout ce qui a divergé depuis une autre branche (git rebase -i main).
Git ouvre votre éditeur configuré avec une ligne par commit, le plus ancien en haut (l'inverse de git log) :
pick a1b2c3d add login form
pick b2c3d4e fix typo
pick c3d4e5f more css tweaksSous la liste, Git inclut un aide-mémoire en commentaires répertoriant toutes les commandes disponibles. Vous changez le mot en début de chaque ligne pour choisir une action, réorganisez éventuellement les lignes, puis sauvegardez et fermez. Git rejoue les commits de haut en bas selon vos instructions. Si vous sauvegardez le fichier sans modification (ou supprimez toutes les lignes), le rebase ne fait rien et s'arrête.
Les commandes de la liste de tâches
Chaque ligne commence par une commande. Voici celles que vous utiliserez le plus souvent :
| Commande | Abréviation | Effet |
|---|---|---|
pick | p | Utiliser le commit tel quel. |
reword | r | Utiliser le commit mais modifier son message. |
edit | e | Faire une pause sur le commit pour en modifier le contenu (amend, division ou ajout de fichiers). |
squash | s | Fusionner dans le commit précédent en combinant les deux messages. |
fixup | f | Comme squash, mais ignorer le message de ce commit. |
drop | d | Supprimer le commit entièrement (supprimer la ligne produit le même effet). |
exec | x | Exécuter une commande shell (par ex. des tests) à ce point du rebase. |
Il n'existe pas de commande reorder — vous réorganisez les commits en déplaçant simplement les lignes vers le haut ou le bas dans la liste de tâches. Les lignes sont appliquées de haut en bas, donc l'ordre que vous laissez est l'ordre que Git crée.
Fusionner des commits avec squash
Un nettoyage courant consiste à regrouper plusieurs petits commits en un seul. Marquez le premier avec pick et les suivants avec squash (ou fixup pour ignorer leurs messages) :
pick a1b2c3d add login form
squash b2c3d4e fix typo
fixup c3d4e5f more css tweakssquash/fixup fusionnent toujours vers le haut, dans la ligne précédente. Lors de la sauvegarde, Git combine les trois en un seul commit. Comme b2c3d4e a été squashé, Git ouvre un second éditeur affichant les deux messages pour que vous puissiez en rédiger un propre ; le fixup de c3d4e5f intègre ses modifications mais supprime silencieusement son message.
Si vous souhaitez simplement regrouper de petits commits "oups" dans un commit antérieur, intéressez-vous à git commit --fixup (voir git commit --amend et git rebase -i --autosquash), qui marque les lignes automatiquement pour vous.
Réécrire un message de commit
Pour corriger une faute de frappe ou clarifier un message sans toucher au code, marquez la ligne avec reword :
pick a1b2c3d add login form
reword b2c3d4e fix tpyo
pick c3d4e5f more css tweaksGit rejoue a1b2c3d tel quel, puis fait une pause et ouvre un éditeur avec l'ancien message de b2c3d4e pour que vous puissiez le réécrire, puis continue. Les modifications du commit ne sont pas touchées — seul le message (et son hash) change.
Réorganiser et supprimer des commits
Pour changer l'ordre, déplacez les lignes. Pour supprimer un commit, marquez-le avec drop ou supprimez la ligne. Cette liste de tâches réorganise la correction CSS avant la correction de faute de frappe et supprime entièrement le commit de faute de frappe :
pick a1b2c3d add login form
pick c3d4e5f more css tweaks
drop b2c3d4e fix typoLa suppression ou la réorganisation peuvent provoquer des conflits si un commit ultérieur dépendait du commit que vous avez supprimé ou déplacé — Git fera une pause et vous laissera les résoudre.
Diviser un commit
Pour découper un grand commit en plusieurs, marquez-le avec edit. Git fait une pause sur ce commit avec les modifications déjà appliquées ; vous annulez alors le commit tout en conservant les modifications, puis recommitez en plusieurs morceaux plus petits :
# rebase pauses on the commit marked 'edit'
git reset HEAD~ # move the commit's changes back to the working tree
git add login.js
git commit -m "add login form markup"
git add styles.css
git commit -m "style the login form"
git rebase --continue # resume the rest of the rebasegit reset HEAD~ annule le dernier commit mais laisse ses modifications dans vos fichiers (voir git reset), vous pouvez ainsi les indexer et les commiter en tant que commits séparés et plus petits.
Terminer ou abandonner
Si une étape provoque un conflit, Git fait une pause pour vous permettre de le résoudre. Modifiez les fichiers en conflit, indexez les corrections avec git add, puis continuez :
git rebase --continueSi vous décidez qu'un commit particulier ne doit pas être appliqué pendant une pause sur un conflit, utilisez git rebase --skip. Pour abandonner tout le rebase et revenir exactement à l'état de départ :
git rebase --abortMême après la fin d'un rebase, les commits d'origine ne sont pas perdus immédiatement — ils restent accessibles via git reflog pendant un certain temps, ce qui constitue le filet de sécurité si vous regrettez un rebase.
Un mot de prudence
Le rebase interactif réécrit l'historique — les commits résultants ont de nouveaux hashes. C'est parfait pour soigner votre propre branche avant d'ouvrir une pull request, mais ne rebasez jamais des commits que d'autres ont déjà récupérés. Réécrire un historique partagé oblige tout le monde à réconcilier des copies divergentes, et pousser le résultat nécessite un force push (git push --force-with-lease). La règle d'or : rebasez localement, fusionnez publiquement.
Si vous avez uniquement besoin de modifier le tout dernier commit, vous n'avez généralement pas besoin d'un rebase complet — git commit --amend est plus simple. Pour copier un seul commit depuis un autre endroit vers votre branche, voir git cherry-pick.
Un exemple complet de squash
Voici une séquence complète que vous pouvez exécuter dans un dossier vide pour voir le squash en action. Elle crée quatre commits, puis regroupe les trois derniers en un seul :
git init -b main demo && cd demo
git config user.email [email protected]
git config user.name You
echo "init" > base && git add base && git commit -m "initial commit"
echo "a" > f && git add f && git commit -m "add login form"
echo -e "a\nb" > f && git add f && git commit -m "fix typo"
echo -e "a\nb\nc" > f && git add f && git commit -m "more css tweaks"
git log --oneline # four commits
git rebase -i HEAD~3 # mark line 2 'squash', line 3 'fixup', save
git log --oneline # now: "initial commit" + one combined commitAprès le rebase, git log --oneline n'affiche plus que deux commits — le commit initial et un seul commit combiné — et le fichier f contient toujours les trois lignes (a, b, c). Le travail est identique ; seul l'historique des commits est plus propre.