Git 🌙
Chapters â–Ÿ 2nd Edition

2.4 Les bases de Git - Annuler des actions

Annuler des actions

À tout moment, vous pouvez dĂ©sirer annuler une de vos derniĂšres actions. Dans cette section, nous allons passer en revue quelques outils de base permettant d’annuler des modifications. Il faut ĂȘtre trĂšs attentif car certaines de ces annulations sont dĂ©finitives (elles ne peuvent pas ĂȘtre elles-mĂȘmes annulĂ©es). C’est donc un des rares cas d’utilisation de Git oĂč des erreurs de manipulation peuvent entraĂźner des pertes dĂ©finitives de donnĂ©es.

Une des annulations les plus communes apparaĂźt lorsqu’on valide une modification trop tĂŽt en oubliant d’ajouter certains fichiers, ou si on se trompe dans le message de validation. Si vous souhaitez rectifier cette erreur, vous pouvez valider le complĂ©ment de modification avec l’option --amend :

$ git commit --amend

Cette commande prend en compte la zone d’index et l’utilise pour le commit. Si aucune modification n’a Ă©tĂ© rĂ©alisĂ©e depuis la derniĂšre validation (par exemple en lançant cette commande immĂ©diatement aprĂšs la derniĂšre validation), alors l’instantanĂ© sera identique et la seule modification Ă  introduire sera le message de validation.

L’éditeur de message de validation dĂ©marre, mais il contient dĂ©jĂ  le message de la validation prĂ©cĂ©dente. Vous pouvez Ă©diter ce message normalement, mais il Ă©crasera le message de la validation prĂ©cĂ©dente.

Par exemple, si vous validez une version puis rĂ©alisez que vous avez oubliĂ© d’indexer les modifications d’un fichier que vous vouliez ajouter Ă  ce commit, vous pouvez faire quelque chose comme ceci :

$ git commit -m 'validation initiale'
$ git add fichier_oublie
$ git commit --amend

Vous n’aurez au final qu’un unique commit — la seconde validation remplace le rĂ©sultat de la premiĂšre.

Note

Il est important de comprendre que lorsque vous ĂȘtre en train de modifier votre dernier commit, vous n’ĂȘtes pas vraiment en train de le rĂ©parer, mais plutĂŽt de le remplacer complĂštement par un commit nouveau, amĂ©liorĂ© qui Ă©carte l’ancien commit et vient Ă  sa place. Dans les faits, c’est comme si l’ancien commit n’avait jamais eu lieu, et il n’apparaĂźtra plus dans l’historique de votre dĂ©pĂŽt.

L’intĂ©rĂȘt immĂ©diat de la rectification de commit est de faire des petites amĂ©liorations de votre dernier commit, sans encombrer l’historique de votre dĂ©pĂŽt avec des messages de validations de la forme « Oups, j’avais oubliĂ© ce fichier » ou « Zut, correction d’une faute sur le dernier commit ».

Note

Ne rectifiez que les commits qui ne sont que locaux et n’ont pas Ă©tĂ© poussĂ©s. La rectification de commit qui ont Ă©tĂ© poussĂ©s et la poussĂ©e en force de branche risque de crĂ©er des problĂšmes avec vos collaborateurs. Pour plus d’information sur ce qui arrive si vous le faites et comment s’en sortir en fin de compte, lisez Les dangers du rebasage

Désindexer un fichier déjà indexé

Les deux sections suivantes dĂ©montrent comment bricoler les modifications dans votre zone d’index et votre zone de travail. Un point sympathique est que la commande permettant de connaĂźtre l’état de ces deux zones vous rappelle aussi comment annuler les modifications. Par exemple, supposons que vous avez modifiĂ© deux fichiers et voulez les valider comme deux modifications indĂ©pendantes, mais que vous avez tapĂ© accidentellement git add * et donc indexĂ© les deux. Comment annuler l’indexation d’un des fichiers ? La commande git status vous le rappelle :

$ git add .
$ git status
Sur la branche master
Votre branche est Ă  jour avec 'origin/master'.
Modifications qui seront validées :
  (utilisez "git reset HEAD <fichier>..." pour désindexer)

    renommé :   README.md -> README
    modifié :   CONTRIBUTING.md

Juste sous le texte « Modifications qui seront validĂ©es », elle vous indique d’utiliser git reset HEAD <fichier>
​ pour dĂ©sindexer un fichier. Utilisons donc ce conseil pour dĂ©sindexer le fichier CONTRIBUTING.md :

$ git reset HEAD CONTRIBUTING.md
Modifications non indexées aprÚs reset :
M       CONTRIBUTING.md
$ git status
Sur la branche master
Votre branche est Ă  jour avec 'origin/master'.
Modifications qui seront validées :
  (utilisez "git reset HEAD <fichier>..." pour désindexer)

        renommé :         README.md -> README

Modifications qui ne seront pas validées :
  (utilisez "git add <fichier>..." pour mettre à jour ce qui sera validé)
  (utilisez "git checkout -- <fichier>..." pour annuler les modifications dans la copie de travail)

        modifié :         CONTRIBUTING.md

La commande Ă  taper peut sembler Ă©trange mais elle fonctionne. Le fichier CONTRIBUTING.md est modifiĂ© mais de retour Ă  l’état non indexĂ©.

Note

git reset peut ĂȘtre une commande dangereuse, surtout conjuguĂ©e avec l’option --hard. Cependant, dans le cas prĂ©sent, le fichier dans la copie de travail n’a pas Ă©tĂ© touchĂ©, donc c’est relativement bĂ©nin.

Pour l’instant, cette invocation magique est la seule Ă  connaĂźtre pour la commande git reset. Nous entrerons plus en dĂ©tail sur ce que reset rĂ©alise et comment le maĂźtriser pour faire des choses intĂ©ressantes dans Reset dĂ©mystifiĂ©

Réinitialiser un fichier modifié

Que faire si vous rĂ©alisez que vous ne souhaitez pas conserver les modifications du fichier CONTRIBUTING.md ? Comment le rĂ©initialiser facilement, le ramener Ă  son Ă©tat du dernier instantanĂ© (ou lors du clonage, ou dans l’état dans lequel vous l’avez obtenu dans votre copie de travail) ? Heureusement, git status vous indique comment procĂ©der. Dans le rĂ©sultat de la derniĂšre commande, la zone de travail ressemble Ă  ceci :

Modifications qui ne seront pas validées :
  (utilisez "git add <fichier>..." pour mettre à jour ce qui sera validé)
  (utilisez "git checkout -- <fichier>..." pour annuler les modifications dans la copie de travail)

        modifié :         CONTRIBUTING.md

Ce qui vous indique de façon explicite comment annuler des modifications que vous avez faites. Faisons comme indiqué :

$ git checkout -- CONTRIBUTING.md
$ git status
Sur la branche master
Votre branche est Ă  jour avec 'origin/master'.
Modifications qui seront validées :
  (utilisez "git reset HEAD <fichier>..." pour désindexer)

        renommé :         README.md -> README

Vous pouvez constater que les modifications ont été annulées.

Important

Vous devriez aussi vous apercevoir que c’est une commande dangereuse : toutes les modifications que vous auriez rĂ©alisĂ©es sur ce fichier ont disparu — vous venez tout juste de l’écraser avec un autre fichier. N’utilisez jamais cette commande Ă  moins d’ĂȘtre vraiment sĂ»r de ne pas vouloir de ces modifications.

Si vous souhaitez seulement écarter momentanément cette modification, nous verrons comment mettre de cÎté et créer des branches dans le chapitre Les branches avec Git ; ce sont de meilleures façons de procéder.

Souvenez-vous, tout ce qui a Ă©tĂ© validĂ© dans Git peut quasiment toujours ĂȘtre rĂ©cupĂ©rĂ©. Y compris des commits sur des branches qui ont Ă©tĂ© effacĂ©es ou des commits qui ont Ă©tĂ© Ă©crasĂ©s par une validation avec l’option --amend (se rĂ©fĂ©rer au chapitre RĂ©cupĂ©ration de donnĂ©es pour la rĂ©cupĂ©ration de donnĂ©es). Cependant, tout ce que vous perdez avant de l’avoir validĂ© n’a aucune chance d’ĂȘtre rĂ©cupĂ©rable via Git.

RĂ©initialiser les choses avec git restore

Git version 2.25.0 a introduit une nouvelle commande : git restore. C’est fondamentalement une alternative Ă  git reset que nous venons de traiter. Depuis Git version 2.25.0, Git utilisera git restore au lieu de git reset pour beaucoup d’opĂ©rations de rĂ©initialisation.

Retraçons nos pas, et réinitialisons les choses avec git restore au lieu de git reset.

Désindexer un fichier indexé avec git restore

Les deux sections suivantes dĂ©montrent comment travailler avec votre zone d’index et votre rĂ©pertoire de travail au moyen de git restore. Le point positif est que la commande que vous utilisez pour dĂ©terminer l’état de ces deux zones vous rappelle comment rĂ©initialiser les modifications qui s’y appliquent. Par exemple, disons que vous avez modifiĂ© deux fichiers et que vous souhaitez les valider comme deux modifications distinctes, mais que vous avez accidentellement tapĂ© git add * et avez indexĂ© les deux. Comment dĂ©sindexer l’une de deux ? la commande git status vous le rappelle :

$ git add *
$ git status
Sur la branche master
Modifications qui seront validées :
  (utilisez "git restore --staged <fichier>..." pour désindexer)
	modifié :   CONTRIBUTING.md
	renommé :   README.md -> README

Juste en dessous du texte “Modifications qui seront validĂ©es”, il nous indique d’utiliser git restore --staged <fichier>
​ pour dĂ©sindexer. Utilisons ce conseil pour dĂ©sindexer le fichier CONTRIBUTING.md.

$ git restore --staged CONTRIBUTING.md
$ git status
Sur la branche master
Modifications qui seront validées :
  (utilisez "git restore --staged <fichier>..." pour désindexer)
	renommé :    README.md -> README

Modifications qui ne seront pas validées :
  (utilisez "git add/rm <fichier>..." pour mettre à jour ce qui sera validé)
  (utilisez "git restore <fichier>..." pour annuler les modifications dans le répertoire de travail)
	modifié :    CONTRIBUTING.md

Le fichier CONTRIBUTING.md est modifié mais une fois de plus non-indexé.

Réinitialiser un fichier modifié avec git restore

Que faire si vous vous apercevez que vous ne voulez pas garder les modifications du fichier CONTRIBUTING.md ? Comment le modifier simplement — le rĂ©initialiser Ă  l’état qu’il avait lors de votre dernier commit (ou lors du clonage ou de toute maniĂšre oĂč il apparaissait dans le dĂ©pĂŽt) ? Heureusement, git status indique aussi comment faire. Dans la sortie du dernier exemple, la zone non-indexĂ©e ressemblait Ă  ceci :

Modifications qui ne seront pas validées :
  (utilisez "git add/rm <fichier>..." pour mettre à jour ce qui sera validé)
  (utilisez "git restore <fichier>..." pour annuler les modifications dans le répertoire de travail)
	modifié :   CONTRIBUTING.md

Cela vous indique assez explicitement comment laisser les modifications que vous avez faites. Faisons comme indiqué :

$ git restore CONTRIBUTING.md
$ git status
Sur la branche master
Modifications qui seront validées :
  (utilisez "git restore --staged <fichier>..." pour désindexer)
	renommé :    README.md -> README
Important

Il faut bien comprendre que git restore <fichier> est une commande dangereuse. Toute modification locale Ă  ce fichier va ĂȘtre perdue — Git remplace ce fichier par la version la plus rĂ©cemment validĂ©e. N’utilisez pas cette commande Ă  moins d’ĂȘtre absolument certain de ne pas vouloir de ces modifications locales.

scroll-to-top