« Mon historique ressemble à un brouillon »
Vous avez avancé vite, et ça se voit : une suite de commits « wip », « oups », « corrige typo », « ça marche enfin ». Ça fonctionne, mais l'historique raconte vos hésitations plutôt que votre travail. Au moment de partager le code, vous aimeriez quelque chose de propre et lisible.
Git permet justement de réécrire l'historique avant de le pousser : corriger un commit, en regrouper plusieurs, en supprimer un, ou récupérer un commit précis d'ailleurs. Cette leçon vous donne les outils pour transformer un brouillon en un historique net. Mais d'abord, une commande pour les urgences du quotidien : git stash.
Mettre son travail de côté avec stash
Vous êtes en plein milieu d'une modification, le code n'est pas prêt à être commité, et là, urgence : il faut basculer sur une autre branche pour corriger un bug. Git refuse de changer de branche tant que votre travail en cours risque d'être écrasé. La solution : git stash, qui met de côté vos modifications non commitées et vous rend un répertoire propre.
# Vous avez des modifs en cours, mais devez changer de branche
$ git stash
Saved working directory and index state WIP on main: a1b2c3d Refonte de l'en-tete
$ git switch fix/bug-urgent
# ... vous corrigez le bug, committez, revenez ...
$ git switch main
# On récupère le travail mis de côté
$ git stash pop
On branch main
Changes not staged for commit:
modified: index.html
git stash range vos modifications dans une pile et nettoie le répertoire. git stash pop les réapplique et retire l'entrée de la pile. Entre les deux, vous étiez libre de naviguer où vous vouliez. git stash list affiche tout ce qui est en attente si vous en avez empilé plusieurs.
Conseil : pensez à git stash comme à un tiroir temporaire. Idéal pour les interruptions : un collègue vous appelle, un bug urgent tombe, vous voulez juste « voir » une autre branche. Vous rangez, vous faites ce que vous avez à faire, puis git stash pop et vous reprenez exactement où vous en étiez.
Des alias pour aller plus vite
Vous tapez git checkout, git status, git commit des dizaines de fois par jour. Git vous laisse créer vos propres raccourcis avec les alias :
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.st status
$ git config --global alias.cm "commit -m"
# Désormais ces deux lignes sont équivalentes :
$ git status
$ git st
L'option --global enregistre l'alias pour tous vos dépôts. Une fois posés, ces raccourcis font partie de votre confort : git st au lieu de git status, git co main au lieu de git checkout main. Vous pouvez même créer des alias pour des commandes longues que vous oubliez toujours, comme un joli journal en une ligne.
Corriger le dernier commit avec amend
Vous venez de committer, et là vous voyez une faute dans le message, ou vous réalisez que vous avez oublié un fichier. Pas besoin d'un nouveau commit « corrige le commit d'avant » : git commit --amend remplace le dernier commit.
# Corriger juste le message du dernier commit
$ git commit --amend -m "Ajoute la page de contact"
# Ou : vous aviez oublié un fichier dans le dernier commit
$ git add styles.css
$ git commit --amend --no-edit # garde le message tel quel
--amend ne modifie pas vraiment le commit : il en crée un nouveau qui le remplace. C'est exactement pour ça qu'il faut être prudent.
Attention, règle d'or : ne réécrivez jamais un historique déjà poussé ou partagé. amend, rebase et reset changent les identifiants des commits. Si vous réécrivez des commits que vos collègues ont déjà tirés, leur dépôt et le vôtre divergent, et la fusion devient un cauchemar. La règle est simple : réécrire l'historique uniquement sur des commits locaux, jamais encore poussés.
Le rebase interactif : nettoyer plusieurs commits
Pour aller au-delà du dernier commit, il y a le rebase interactif. git rebase -i HEAD~3 ouvre un éditeur listant vos 3 derniers commits, et vous laisse décider quoi faire de chacun :
$ git rebase -i HEAD~3
# Git ouvre un éditeur avec :
pick a1b2c3d Ajoute le formulaire de contact
pick d4e5f6a Oups, corrige typo
pick b7c8d9e wip css du formulaire
Vous remplacez le mot pick au début de chaque ligne par l'action voulue :
pick— garde le commit tel quel.reword— garde le commit mais permet de réécrire son message.squash— fusionne ce commit avec le précédent, en combinant les deux messages.fixup— comme squash, mais jette le message de ce commit (idéal pour absorber un « oups, corrige typo »).edit— met le rebase en pause sur ce commit pour le modifier en profondeur.drop— supprime complètement le commit de l'historique.
# Résultat souhaité : un seul commit propre
pick a1b2c3d Ajoute le formulaire de contact
fixup d4e5f6a Oups, corrige typo
fixup b7c8d9e wip css du formulaire
Vous sauvegardez, fermez l'éditeur, et Git rejoue l'historique selon vos instructions. Les trois commits brouillons deviennent un seul commit clair. C'est l'outil idéal pour nettoyer une branche juste avant de la pousser.
Récupérer un commit précis avec cherry-pick
Parfois, vous voulez un seul commit d'une autre branche, sans fusionner toute la branche. Par exemple, une correction faite sur fix/bug que vous voulez aussi sur main tout de suite. git cherry-pick copie un commit précis sur votre branche actuelle :
# On récupère le hash du commit voulu (avec git log)
$ git log --oneline fix/bug
9f8e7d6 Corrige le calcul de la TVA
...
# On est sur main, on applique juste ce commit
$ git switch main
$ git cherry-pick 9f8e7d6
[main 3c4d5e6] Corrige le calcul de la TVA
Le commit est recopié sur main avec un nouvel identifiant. Pratique pour transporter un correctif d'une branche à l'autre sans tout fusionner, ou pour récupérer un commit qui s'est retrouvé sur la mauvaise branche.
Récapitulatif
git stash/git stash pop— mettre de côté son travail non commité, puis le récupérer.git config --global alias.xx— créer des raccourcis pour vos commandes courantes.git commit --amend— corriger le dernier commit (message ou fichier oublié).git rebase -i— nettoyer plusieurs commits : reword, squash, fixup, edit, drop.git cherry-pick— copier un commit précis depuis une autre branche.
Le fil rouge : on réécrit l'historique uniquement en local, avant de pousser. Une fois partagé, on n'y touche plus.
"My history looks like a rough draft"
You moved fast, and it shows: a string of commits like "wip", "oops", "fix typo", "finally works". It works, but the history tells the story of your hesitations rather than your work. When it is time to share the code, you would like something clean and readable.
Git lets you do exactly that: rewrite history before pushing it. Fix a commit, group several together, drop one, or grab a specific commit from elsewhere. This lesson gives you the tools to turn a rough draft into a clean history. But first, a command for everyday emergencies: git stash.
Setting work aside with stash
You are in the middle of a change, the code is not ready to commit, and then comes an emergency: you have to switch to another branch to fix a bug. Git refuses to switch branches as long as your work in progress might be overwritten. The solution: git stash, which sets your uncommitted changes aside and gives you a clean working directory.
# You have changes in progress, but must switch branches
$ git stash
Saved working directory and index state WIP on main: a1b2c3d Rebuild the header
$ git switch fix/urgent-bug
# ... you fix the bug, commit, come back ...
$ git switch main
# Bring back the work you set aside
$ git stash pop
On branch main
Changes not staged for commit:
modified: index.html
git stash tucks your changes onto a stack and cleans the directory. git stash pop reapplies them and removes the entry from the stack. In between, you were free to navigate wherever you wanted. git stash list shows everything pending if you have stacked several.
Tip: think of git stash as a temporary drawer. Perfect for interruptions: a colleague calls, an urgent bug drops in, you just want to "peek" at another branch. You tuck things away, do what you need, then git stash pop and you are exactly where you left off.
Aliases to move faster
You type git checkout, git status, git commit dozens of times a day. Git lets you create your own shortcuts with aliases:
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.st status
$ git config --global alias.cm "commit -m"
# Now these two lines are equivalent:
$ git status
$ git st
The --global option saves the alias for all your repositories. Once set, these shortcuts become part of your comfort: git st instead of git status, git co main instead of git checkout main. You can even create aliases for long commands you always forget, like a nice one-line log.
Fixing the last commit with amend
You just committed, and then you spot a typo in the message, or you realize you forgot a file. No need for a new "fix the previous commit" commit: git commit --amend replaces the last commit.
# Fix just the message of the last commit
$ git commit --amend -m "Add the contact page"
# Or: you forgot a file in the last commit
$ git add styles.css
$ git commit --amend --no-edit # keeps the message as is
--amend does not really modify the commit: it creates a new one that replaces it. That is exactly why you have to be careful.
Warning, golden rule: never rewrite history that has already been pushed or shared. amend, rebase and reset change commit identifiers. If you rewrite commits your colleagues have already pulled, their repository and yours diverge, and merging becomes a nightmare. The rule is simple: only rewrite history on local commits, never yet pushed.
Interactive rebase: cleaning up several commits
To go beyond the last commit, there is the interactive rebase. git rebase -i HEAD~3 opens an editor listing your last 3 commits, and lets you decide what to do with each:
$ git rebase -i HEAD~3
# Git opens an editor with:
pick a1b2c3d Add the contact form
pick d4e5f6a Oops, fix typo
pick b7c8d9e wip form css
You replace the word pick at the start of each line with the action you want:
pick— keep the commit as is.reword— keep the commit but let you rewrite its message.squash— merge this commit into the previous one, combining both messages.fixup— like squash, but discard this commit's message (perfect to absorb an "oops, fix typo").edit— pause the rebase on this commit to modify it in depth.drop— remove the commit from history entirely.
# Desired result: a single clean commit
pick a1b2c3d Add the contact form
fixup d4e5f6a Oops, fix typo
fixup b7c8d9e wip form css
You save, close the editor, and Git replays the history according to your instructions. The three rough commits become a single clear one. It is the ideal tool to clean up a branch just before pushing it.
Grabbing a specific commit with cherry-pick
Sometimes you want a single commit from another branch, without merging the whole branch. For example, a fix made on fix/bug that you also want on main right now. git cherry-pick copies a specific commit onto your current branch:
# Get the hash of the wanted commit (with git log)
$ git log --oneline fix/bug
9f8e7d6 Fix the VAT calculation
...
# We are on main, apply just that commit
$ git switch main
$ git cherry-pick 9f8e7d6
[main 3c4d5e6] Fix the VAT calculation
The commit is copied onto main with a new identifier. Handy to carry a fix from one branch to another without merging everything, or to recover a commit that ended up on the wrong branch.
Recap
git stash/git stash pop— set uncommitted work aside, then bring it back.git config --global alias.xx— create shortcuts for your common commands.git commit --amend— fix the last commit (message or forgotten file).git rebase -i— clean up several commits: reword, squash, fixup, edit, drop.git cherry-pick— copy a specific commit from another branch.
The common thread: you rewrite history only locally, before pushing. Once shared, you leave it alone.
Le rebase interactif fait peur ? Faites-vous guider pas à pas par l'IA :
J'ai 4 derniers commits locaux pas encore poussés, avec des messages brouillons comme 'wip' et 'oups typo'. Je veux les regrouper en un ou deux commits propres avec git rebase -i HEAD~4. Explique-moi en français, étape par étape, comment remplir l'éditeur (pick, squash, fixup, reword), ce qui va se passer à chaque étape, et comment m'en sortir si je me trompe. Rappelle-moi aussi la règle de sécurité sur l'historique déjà partagé.
Sans relire la réponse de l'IA : dans un git rebase -i, à quoi servent squash, fixup et reword, et en quoi diffèrent-ils ?
squash fusionne le commit avec le précédent en gardant et combinant les deux messages ; fixup fait pareil mais jette le message de ce commit (idéal pour absorber un « oups, typo ») ; reword garde le commit tel quel mais ouvre l'éditeur pour réécrire son message. Les deux premiers réduisent le nombre de commits, le troisième n'en change que le texte.Écrivez les commandes pour : mettre votre travail en cours de côté (git stash), puis (plus tard) le récupérer (git stash pop), et enfin lancer un rebase interactif sur vos 3 derniers commits (git rebase -i HEAD~3).
L'IA propose ces commandes pour « nettoyer un peu » la branche main partagée du projet. Ton rôle de relecteur : les accepter telles quelles ou les rejeter, et dire pourquoi.
$ git switch main
$ git rebase -i HEAD~5
$ git push --force origin main
rebase -i) puis on force (push --force) des commits déjà partagés sur main. Les identifiants des 5 commits changent, et le dépôt de chaque collègue qui les avait déjà tirés diverge du dépôt distant. La fusion devient un cauchemar et du travail peut être perdu. On ne réécrit l'historique qu'en local, sur des commits pas encore poussés. Si un partage forcé est vraiment nécessaire (rare), au minimum --force-with-lease et un accord explicite de l'équipe, jamais en solo sur main.Sans remonter dans la leçon : que fait git commit --amend, et quelle est la règle d'or à respecter avant de réécrire des commits ?
git commit --amend remplace le dernier commit : il sert à corriger son message (--amend -m) ou à y ajouter un fichier oublié (git add puis --amend --no-edit). En réalité il ne modifie rien, il crée un nouveau commit qui prend la place de l'ancien, donc l'identifiant change. La règle d'or : ne jamais réécrire (amend, rebase, reset) un historique déjà poussé ou partagé ; uniquement sur des commits locaux.Vous tenez maintenant toute la boîte à outils : terminal, Git, branches, GitHub, conflits, et la réécriture propre de l'historique. Il ne reste qu'une chose à faire : mettre tout ça en pratique sur de vrais projets, du début à la fin.
Passer aux projets →