Remove, delete, cancel ou undo — quel que soit le verbe recherché, la commande qui garde les changements est la même. Trois commandes couvrent presque tous les
Annuler le dernier commit en gardant les changements : git reset --soft HEAD~1 (staged) ou git reset HEAD~1 (unstaged).
Déjà poussé ? git revert HEAD — un nouveau commit qui l'annule, sans danger sur les branches partagées.
reset --hard est la seule ligne qui supprime du travail — et git reflog le sait encore, pendant ~90 jours.
Un commit de trop, trois sorties. Le drapeau décide où atterrissent vos changements — suivez les voies :
fig — la seule voie qui supprime du travail est --hard ; le reflog est le caniveau qui coule sous les trois
La situation la plus courante : vous avez commité, puis repéré une coquille, un fichier manquant, ou compris que la modification appartient à un autre commit. Rien n'est poussé. Annulez le commit et remettez tout en place :
# commit parti — les changements retournent dans la zone de staging
git reset --soft HEAD~1
# les changements retournent dans l'arbre de travail (unstaged) à la place
git reset HEAD~1
HEAD~1 signifie « un commit avant là où HEAD pointe maintenant ». Après l'une ou l'autre commande, vos fichiers sont intacts sur disque — seul le pointeur de branche a bougé. Vérifiez avec git status: with --soft les changements sont staged, prêts à être recommités avec les corrections ; sans drapeau ils sont unstaged, donc éditables librement d'abord.
vérifiez : git status → staged (--soft) ou unstaged (défaut) · git log --oneline -1 → le commit d'avant
Habitude plus sûre quand vous voulez seulement ajouter des fichiers au dernier commit : ne l'annulez pas du tout :
git add forgotten-file.txt
git commit --amend --no-edit
--amend remplace le dernier commit sur place (message inchangé ici). Notez qu'amender un commit poussé réécrit l'histoire — plus bas.
C'est la partie à mémoriser, car le drapeau décide où finissent vos changements — et s'ils peuvent être perdus :
| Drapeau | Commit annulé ? | Changements sur disque | Staged ? | Usage typique |
|---|---|---|---|---|
--soft | Oui | Conservés | Yes | Recommiter avec petites corrections |
--mixed (défaut) | Oui | Conservés | No | Regrouper les changements, re-stage sélectif |
--hard | Oui | Supprimés | — | Jeter le travail entièrement |
git revert | Non (nouveau commit) | Conservés | — | Annuler un commit déjà poussé |
--hard est le seul dangereux : il jette le commit et les changements. Avant tout hard reset, stash ou branchez ce que vous avez :
git branch backup-before-reset # assurance pas chère
git reset --hard HEAD~1 # commit + changements disparus
Déjà lancé la version dangereuse ? Tout n'est pas perdu — git reflog se souvient d'où HEAD est passé. Le reflog garde les commits pendants ~90 jours par défaut, donc « j'ai fait un hard-reset par erreur » est presque toujours récupérable si vous agissez avant le garbage collection :
git reflog # ou : git reset --hard <hash>
git reset --hard HEAD@{1} # or: git reset --hard <hash>
vérifiez : git reflog → le commit abandonné est à HEAD@{1}
L'historique partagé reçoit un nouveau commit, jamais une réécriture. Si le commit est sur une branche partagée — tout sauf votre propre branche de fonctionnalité — ne réécrivez pas l'histoire. git revert calcule le changement inverse et le commite. Tous ceux qui pull reçoivent simplement un nouveau commit qui retire les changements de l'ancien. Pas de force-push, pas de collègues cassés :
git revert HEAD
git push
Undoing a run of commits is the same move over a range: Annuler une série de commits est le même geste sur une plage : . The alternative — — n'est acceptable que sur une branche que personne d'autre ne construit : — is only acceptable on a branch nobody else builds on: --force-with-lease refuse le push si le distant a bougé depuis votre dernier fetch ; un simple --force écrase tout ce qui est apparu. Forcer le push de branches partagées, c'est ainsi que les équipes perdent des commits et que les logs CI cessent mystérieusement de correspondre au checkout de quiconque.
vérifiez : git log --oneline -2 → Revert "…" se pose au-dessus du commit annulé
Parfois le commit est bon — mauvaise branche, ou trop tôt. Au lieu de l'annuler, déplacez-le. Garez le commit entier sur une nouvelle branche, puis nettoyez votre
git branch stash-commit # garez le commit sur une nouvelle branche
git reset --hard HEAD~1 # puis nettoyez votre branche courante
git cherry-pick <hash> # depuis la branche cible
Entre reset --soft, cherry-pick et revert, il n'existe aucun commit que vous ne puissiez déplacer ou annuler — l'astuce est de choisir « déplacer » contre « annuler » avant de tendre la main vers un drapeau.
La moitié de la confusion est du vocabulaire : six verbes tapés dans la recherche, trois commandes qui existent vraiment. Faites correspondre le mot dans votre tête au drapeau qui le fait :
| Le mot tapé | Ce que vous voulez | La commande | Changements gardés ? |
|---|---|---|---|
| undo / uncommit | commit parti, travail rendu | git reset --soft HEAD~1 | oui — staged |
| undo, unstaged | commit parti, travail rendu en vrac | git reset HEAD~1 | oui — mixed |
| remove / drop | commit et éditions disparus | git reset --hard HEAD~1 | non — reflog ~90 jours |
| revert / cancel, poussé | annulation publique, histoire intacte | git revert HEAD | oui — nouveau commit |
Les verbes ne sont pas des synonymes en Git : revert ne touche jamais le passé, reset le réécrit. Dites le mauvais mot à un collègue et vous obtenez la mauvaise commande. Toute la décision, en liste de contrôle :
git reset --soft HEAD~1git reset HEAD~1 (mixed)git reset --hard HEAD~1 (le reflog sait, si vous regrettez)git revert HEADcherry-pick, n'annulez pasVous voulez qu'on décide pour vous ? Le générateur git-undo pose ces questions et imprime la commande. Un dernier conseil d'exploitation : si un mauvais commit est réellement parti vers un serveur — hook de déploiement raté, coureur CI qui déraille après un force-push — le prochain endroit à regarder, ce sont les logs de la machine, pas Git : sur toute machine systemd, journalctl -u <service> -n 100 shows you exactly what ran and when. And when Git refuses to run at all — fatal: not a git repository — that is a different problem from undoing anything.
fin de la page annulation · rien de récupéré · tout est local