Rez-de-chausséeG GitPièce 5/7Intermédiaire

Annuler une erreur

Annuler une modification, désindexer un fichier, corriger le dernier commit, revenir en arrière avec revert ou reset, sans réécrire un historique déjà poussé.

Ce que tu vas apprendre

  • Annuler une modification ou une indexation avec git restore.
  • Défaire un commit proprement avec git revert, ou reculer avec git 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 :

SituationCommande
Fichier modifié, pas encore indexégit restore fichier
Fichier indexé par erreurgit restore --staged fichier
Dernier commit à corriger, pas encore pousségit commit --amend
Commit déjà poussé à défairegit revert
Commits locaux à abandonnergit 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.

Annuler avec revert 1 / 2
C1C2C3C4mainHEAD
$ git log --oneline

C4 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 :

OptionDéplace HEADRemet l'index à ce commitRemet tes fichiers à ce commit
--softouinonnon
--mixed (par défaut)ouiouinon
--hardouiouioui

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
Revenir en arrière avec reset 1 / 3
C1C2C3C4mainHEAD
$ git log --oneline

Quatre 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é.

Un commit est déjà poussé ? Utilise git revert. Il n'est que sur ta machine ? git reset ou git commit --amend conviennent.

À retenir

  • git restore fichier annule une modification, git restore --staged fichier la retire de l'index.
  • git commit --amend corrige le dernier commit, s'il n'est pas encore poussé.
  • git revert ajoute un commit inverse : c'est la bonne méthode pour un commit déjà partagé.
  • git reset recule la branche : --soft garde l'index, --mixed garde les fichiers, --hard efface aussi les modifications de tes fichiers.
  • git reflog retrouve un commit perdu après un reset.

Pour aller plus loin

Sources officielles

Ensuite

Projet
Lignes de code
Niveau
Rez-de-chaussée
Appartement
Git
Pièce
5/7
Plan n°
git/05.annuler
Lignes de code · fiches rédigées à partir des documentations officielles, sources citées en bas de chaque page.