Introduction
Git fournit plusieurs façons d'annuler, selon que le changement soit dans votre arborescence de travail, dans l'index, dans votre dernier commit, ou déjà poussé. Choisir le bon outil prévient les accidents.
Abandonner les éditions de l'arborescence de travail
Vous avez édité un fichier mais vous voulez jeter les changements :
git restore file.txt # moderne
git checkout -- file.txt # équivalent classique
git restore sans --source utilise l'index, donc le fichier revient à son dernier état git add.
Désindexer (unstage)
Vous avez exécuté git add mais vous voulez retirer un fichier du prochain commit (sans perdre les éditions) :
git restore --staged file.txt
git reset HEAD file.txt # syntaxe ancienne
Amender le dernier commit
Vous avez commité mais vous voulez corriger le message ou inclure un autre fichier :
git commit --amend -m "Better message"
git add forgotten.txt
git commit --amend --no-edit
N'amendez que les commits que vous n'avez pas poussés, ou soyez prêt à force-pusher.
Reverter un commit public
Si un mauvais commit est déjà poussé, ne réécrivez pas l'historique. Créez un nouveau commit qui l'annule :
git revert <sha>
git push
git revert ouvre un éditeur avec un message généré ; le résultat est une annulation propre que tout le monde peut puller.
Resetter
git reset déplace le pointeur de la branche courante. Il a trois modes :
--soft: déplace seulement la branche ; garde l'index et l'arborescence de travail.--mixed(défaut) : déplace la branche et reset l'index ; garde l'arborescence de travail.--hard: déplace la branche, reset l'index, reset l'arborescence de travail. Destructif.
git reset --soft HEAD~1 # décommiter, garder les changements stagés
git reset HEAD~1 # décommiter, garder les changements non stagés
git reset --hard HEAD~1 # détruire le dernier commit et les changements
Récupérer après --hard
git reflog
git reset --hard HEAD@{1}
Le reflog se souvient de chaque mouvement de HEAD pendant 90 jours.
Choisir la bonne annulation
Une matrice de décision simple :
- Arborescence de travail seulement :
git restore <file> - Fichier stagé :
git restore --staged <file> - Dernier commit non poussé :
git commit --amendougit reset --soft HEAD~1 - Commit poussé :
git revert <sha> - Pointe de branche entière :
git reset --hard ORIG_HEAD(après un mauvais merge/rebase)
git status
git diff
git log --oneline -5
Exécutez toujours ces trois commandes avant toute annulation destructive. Elles montrent l'arborescence de travail, les changements stagés et l'historique récent ; ensemble, elles vous disent quelle annulation est sûre.
Erreurs fréquentes
Confondre revert avec reset. Revert ajoute ; reset retire. Exécuter git reset --hard avec du travail non commité, puis se rendre compte qu'on en avait besoin ; allez immédiatement au reflog, avant que le garbage collection ne tourne. Amender un commit poussé sans coordonner le force-push avec les coéquipiers. Utilisez git revert sur l'historique partagé. Et enfin, traiter git checkout file comme sûr ; dans les anciens Git, il écrase silencieusement vos éditions sans corbeille. Le moderne git restore n'est pas différent ; sauvegardez d'abord en cas de doute.