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

■ the answer first

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.

LES TROIS VOIES

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

GARDER LES CHANGEMENTS : LES DEUX COMMANDES

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.

LES TROIS DRAPEAUX, CÔTE À CÔTE

C'est la partie à mémoriser, car le drapeau décide où finissent vos changements — et s'ils peuvent être perdus :

DrapeauCommit annulé ?Changements sur disqueStaged ?Usage typique
--softOuiConservésYesRecommiter avec petites corrections
--mixed (défaut)OuiConservésNoRegrouper les changements, re-stage sélectif
--hardOuiSupprimés—Jeter le travail entièrement
git revertNon (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}

DÉJÀ POUSSÉ ?

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é

DU BON TRAVAIL, MAUVAISE ADRESSE

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.

LE MOT EST LA COMMANDE

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 voulezLa commandeChangements gardés ?
undo / uncommitcommit parti, travail rendugit reset --soft HEAD~1oui — staged
undo, unstagedcommit parti, travail rendu en vracgit reset HEAD~1oui — mixed
remove / dropcommit et éditions disparusgit reset --hard HEAD~1non — reflog ~90 jours
revert / cancel, pousséannulation publique, histoire intactegit revert HEADoui — 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 :

  1. Non poussé, corriger et recommiter → git reset --soft HEAD~1
  2. Non poussé, re-stage sélectif → git reset HEAD~1 (mixed)
  3. Voir les changements disparaître complètement → git reset --hard HEAD~1 (le reflog sait, si vous regrettez)
  4. Déjà poussé sur une branche partagée → git revert HEAD
  5. Le commit appartient à une autre branche → cherry-pick, n'annulez pas

Vous 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.

■ honest stamp Testé sur : git 2.4x · Linux · macOS · Windows — chaque commande tourne telle quelle. Première publication 2026-09-03, fiche actualisée 2026-10-09. La table des drapeaux, la fenêtre de ~90 jours du reflog et le comportement de force-with-lease sont les défauts documentés de git, tapés à l'usage ; rien sur cette page n'est de la syntaxe hypothétique.

fin de la page annulation · rien de récupéré · tout est local