Annuler une erreur
Ce que tu vas apprendre
- Annuler une modification ou une indexation avec
git restore. - Défaire un commit proprement avec
git revert, ou reculer avecgit reset. - La règle d'or : ne pas réécrire un historique déjà poussé.
Choisir le bon outil
La bonne commande dépend de l'endroit où se trouve l'erreur :
| Situation | Commande |
|---|---|
| Fichier modifié, pas encore indexé | git restore fichier |
| Fichier indexé par erreur | git restore --staged fichier |
| Dernier commit à corriger, pas encore poussé | git commit --amend |
| Commit déjà poussé à défaire | git revert |
| Commits locaux à abandonner | git reset |
La BD xkcd 1597 se moque de ceux qui, au moindre problème, suppriment le dossier et re-clonent le projet. Ce chapitre sert à ne plus en arriver là.
Annuler une modification : git restore
Tu as cassé style.css en essayant une nouvelle mise en page, et tu veux revenir à la dernière version enregistrée :
git restore style.css
Le fichier reprend son contenu de l'index, c'est-à-dire celui du dernier commit si tu ne l'avais pas indexé.
git restore sur un fichier efface tes modifications non enregistrées. Git ne les a jamais vues : il ne pourra pas te les rendre.Désindexer un fichier : git restore --staged
Tu as fait git add . et un fichier de test est parti dans l'index :
git restore --staged test.html
Le fichier sort de l'index mais garde ses modifications dans ton dossier. Rien n'est perdu.
Tu verras git checkout et git reset utilisés pour ces deux cas dans d'anciens tutoriels. git restore est la commande recommandée aujourd'hui.
Corriger le dernier commit : git commit --amend
Une faute dans le message, ou un fichier oublié ? Indexe ce qui manque, puis :
git add contact.html
git commit --amend -m "Ajoute la page contact"
Git remplace le dernier commit par un nouveau, avec un nouvel identifiant. C'est une réécriture de l'historique : ne le fais que si ce commit n'a pas encore été poussé.
Défaire un commit poussé : git revert
Le commit qui a ajouté le nouveau menu casse le site en production, et il est déjà sur GitHub. Tes collègues l'ont récupéré. Tu ne peux pas le faire disparaître sans les gêner. git revert crée un nouveau commit qui applique l'inverse :
git revert HEAD
HEAD désigne le commit actuel. Tu peux aussi donner l'identifiant d'un commit plus ancien, lu dans git log --oneline. L'historique est conservé : on voit l'erreur, puis sa correction.
$ git log --onelineC4 a déjà été poussé et des collègues l’ont récupéré : on ne réécrit pas l’historique.
Reculer : git reset
git reset déplace la branche courante vers un commit plus ancien. Les commits suivants ne font plus partie de la branche. Son option décide de ce qu'il advient de tes fichiers :
| Option | Déplace HEAD | Remet l'index à ce commit | Remet tes fichiers à ce commit |
|---|---|---|---|
--soft | oui | non | non |
--mixed (par défaut) | oui | oui | non |
--hard | oui | oui | oui |
Concrètement, pour reculer d'un commit :
git reset --soft HEAD~1: les changements du commit annulé restent indexés, prêts à être validés autrement.git reset HEAD~1: ils restent dans tes fichiers, mais ne sont plus indexés.git reset --hard HEAD~1: ils disparaissent aussi de tes fichiers.
HEAD~1 signifie « le commit juste avant HEAD ».
git reset --hard écrase aussi les modifications non commitées de ton dossier. Celles-là sont perdues pour de bon. Lance git status avant.Rattraper un reset avec git reflog
Un commit retiré par git reset n'est pas effacé tout de suite. git reflog liste les positions récentes de HEAD, avec leurs identifiants. Tu retrouves celui du commit perdu, et tu reviens dessus :
git reflog
git reset --hard a1b2c3d
$ git log --onelineQuatre commits. On veut abandonner C4, qui n’a pas encore été poussé.
La règle : ne pas réécrire un historique poussé
git commit --amend et git reset réécrivent l'historique. Sur des commits qui ne sont que chez toi, aucun problème. Sur des commits déjà poussés, tes collègues ont une autre version de l'histoire. Pour publier la tienne, il faudrait forcer le git push, et leur travail pourrait être écrasé.
git revert. Il n'est que sur ta machine ? git reset ou git commit --amend conviennent.À retenir
git restore fichierannule une modification,git restore --staged fichierla retire de l'index.git commit --amendcorrige le dernier commit, s'il n'est pas encore poussé.git revertajoute un commit inverse : c'est la bonne méthode pour un commit déjà partagé.git resetrecule la branche :--softgarde l'index,--mixedgarde les fichiers,--hardefface aussi les modifications de tes fichiers.git reflogretrouve un commit perdu après un reset.
Pour aller plus loin
Sources officielles
Ensuite
Travailler à plusieurs
Relier ton dépôt à un dépôt distant, cloner, envoyer et récupérer des commits avec push, fetch et pull, et proposer tes changements par pull request.
Le rebase
Rejouer une branche par-dessus une autre avec git rebase, comparer avec git merge, et savoir quand ne jamais l'utiliser.
- Projet
- Lignes de code
- Niveau
- Rez-de-chaussée
- Appartement
- Git
- Pièce
- 5/7
- Plan n°
- git/05.annuler