Git : annuler et corriger
Git permet presque toujours de revenir en arrière. Le choix de la commande dépend de où en est la modification et de son partage avec d’autres.
Quelle commande choisir ?
Section intitulée « Quelle commande choisir ? »| Situation | Commande |
|---|---|
| Annuler des modifications non ajoutées | git restore fichier |
| Retirer un fichier de l’index (avant commit) | git restore --staged fichier |
| Corriger le dernier commit (non poussé) | git commit --amend |
| Annuler un commit déjà poussé | git revert |
| Défaire des commits locaux | git reset |
| Mettre de côté des modifications | git stash |
| Retrouver un commit « perdu » | git reflog |
Annuler des modifications de fichiers
Section intitulée « Annuler des modifications de fichiers »git restore fichier.txt # remet le fichier dans l'état du dernier commitgit restore . # tous les fichiers modifiésgit restore --staged fichier.txt # désindexe (garde les modifications dans le fichier)git restore --source=HEAD~2 fichier.txt # récupère le fichier tel qu'il était 2 commits plus tôtCorriger le dernier commit : --amend
Section intitulée « Corriger le dernier commit : --amend »git commit --amend -m "fix(auth): correct login redirect" # change seulement le messagegit add oubli.txtgit commit --amend --no-edit # ajoute un fichier oublié au dernier commit--amend réécrit le commit : à n’utiliser que s’il n’est pas encore poussé (sinon voir --force-with-lease dans Dépôts distants).
Défaire des commits : git reset
Section intitulée « Défaire des commits : git reset »git reset --soft HEAD~1 # annule le dernier commit, garde les modifications dans l'indexgit reset HEAD~1 # idem (--mixed), garde les modifications dans les fichiers, non indexéesgit reset --hard HEAD~1 # annule le commit ET supprime les modificationsgit reset --hard origin/main # aligne la branche locale sur le dépôt distant (perd le travail local)| Mode | Commits | Index | Fichiers |
|---|---|---|---|
--soft |
annulés | conservé | conservés |
--mixed (défaut) |
annulés | vidé | conservés |
--hard |
annulés | vidé | supprimés |
Annuler un commit déjà partagé : git revert
Section intitulée « Annuler un commit déjà partagé : git revert »revert crée un nouveau commit qui annule les effets d’un commit existant, sans réécrire l’historique :
git revert a1b2c3d # annule ce commitgit revert HEAD # annule le derniergit revert -m 1 <commit-de-fusion> # annule une fusion (garde le parent 1)git revert --no-commit a1b2c3d..e4f5g6h # plusieurs commits en un seulMettre de côté : git stash
Section intitulée « Mettre de côté : git stash »Pour changer de branche sans valider un travail en cours :
git stash # met de côté les modifications suiviesgit stash -u # inclut aussi les fichiers non suivisgit stash push -m "essai de la recherche"git stash listgit stash pop # réapplique le dernier stash et le supprimegit stash apply stash@{1} # réapplique sans supprimergit stash drop stash@{0}git stash show -p stash@{0} # contenuRetrouver un commit perdu : git reflog
Section intitulée « Retrouver un commit perdu : git reflog »Le reflog enregistre chaque déplacement de HEAD (commits, resets, changements de branche) :
git reflog # historique des positions de HEADgit switch -c secours a1b2c3d # recrée une branche sur un commit retrouvégit reset --hard HEAD@{2} # revient à l'état d'il y a 2 mouvementsLes entrées du reflog sont conservées environ 90 jours (30 jours pour les commits inaccessibles), en local seulement.
Nettoyer les fichiers non suivis
Section intitulée « Nettoyer les fichiers non suivis »git clean -n # simulation : liste ce qui serait supprimégit clean -fd # supprime fichiers et dossiers non suivisgit clean -fdx # supprime aussi les fichiers ignorésUn secret a été validé par erreur
Section intitulée « Un secret a été validé par erreur »- Révoquer immédiatement le secret (mot de passe, jeton, clé) chez son émetteur : même supprimé, il reste dans l’historique et dans toutes les copies déjà récupérées.
- Si le commit n’est pas poussé :
git reset --soft HEAD~1, retirer le secret, recommiter. - Sinon, réécrire l’historique avec
git filter-repo(outil externe :sudo apt install git-filter-repo) :
git filter-repo --path .env --invert-paths # retire le fichier .env de tout l'historiquegit push --force-with-lease --allTous les collaborateurs doivent ensuite re-cloner le dépôt. La révocation reste l’action essentielle.
Trouver l’origine d’un bug : git bisect
Section intitulée « Trouver l’origine d’un bug : git bisect »git bisect startgit bisect bad # le commit actuel est défectueuxgit bisect good v1.0.0 # cette version fonctionnait# Git propose un commit intermédiaire : tester, puis indiquer git bisect good ou git bisect badgit bisect reset # terminer et revenirPour aller plus loin
Section intitulée « Pour aller plus loin »- Manuel : Undoing Things et Reset Demystified
- Suite : Configuration