Revert : annuler un commit
Un exemple simple
Partons de l’historique suivant (les valeurs hexadécimales sont les identifiants des commits en version abrégée) :
* 60b3490 - (HEAD -> main) Update f1
* cf98449 - Update f2
* 067214a - Add f2
* 7b45b93 - Add f1
Je souhaite annuler le travail du commit « Update f2 ». Je lance alors la commande :
git revert 067214a
L’éditeur s’ouvre et nous propose le message automatique suivant :
Revert "Update f2"
This reverts commit cf98449fe204128011fe38a8e462ac0fa81ee57d.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch main
# Changes to be committed:
# modified: f2.txt
#
En général, on laisse le message tel quel. Sauf en cas de conflits avec des modifications plus récentes, le travail s’arrête là. On peut regarder l’historique après notre opération :
* 65c44fa - (HEAD -> main) Revert "Update f2"
* 60b3490 - Update f1
* cf98449 - Update f2
* 067214a - Add f2
* 7b45b93 - Add f1
On voit donc ce nouveau commit Revert "Update f2"
qui vient annuler celui qu’on lui a donné.
Et si j’ai un conflit ?
Tu rencontreras des conflits si les fichiers qui doivent être en partie « défaits » par le revert ont subit des modifications aux endroits qui doivent être modifiés par Git. Si tu travailles dans le terminal, tu auras droit à un message du type :
Auto-merging f2.txt
CONFLICT (content): Merge conflict in f2.txt
error: could not revert cf98449... Update f2
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git revert --continue".
hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort".
Merci Git, la procédure y est décrite. Tu arbitres donc ton conflit, puis tu lances git revert --continue
, c’est tout !
Si jamais tu préfères abandonner, ne pas arbitrer et laisser tomber ton revert, un git revert --abort
te remettra dans la situation d’avant ta commande.
Quelques astuces en plus !
Si tu ne souhaites pas éditer le messages proposé par revert, tu peux utiliser l’option --no-edit
.
Tu peux aussi passer plusieurs commits à la commande pour qu’elle les traite à la chaîne. C’est rarement un besoin réel, mais on ne sait jamais.
Revert vs rebase et reset ?
Si tu es déjà un·e utilisat·eur·rice averti·e de Git, tu sais probablement que tu peux annuler « proprement » des commits, selon le contexte, avec les commandes reset ou rebase. Dans ce cas, la commande revert est-elle pertinente ? À cette question, je ne peux que te donner une réponse de normand : p’t-ête ben qu’oui, p’t-ête ben qu’non ! Car oui, ça dépend du contexte, mais aussi des règles fixées sur le projet, de ton aisance avec ces commandes…
Voici malgré tout ma préférence : je n’utilise presque jamais revert. Le seul cas où je juge son emploi pertinent est après une fusion sur un tronc commun (idéalement une fusion en mode squash). Le commit résultant du squashed merge contient toute la fonctionnalité intégrée. Le revert de ce commit revient donc à annuler l’ajout de la fonctionnalité au tronc commun (la branche de production ou équivalence). C’est ici une solution de facilité qui permet aussi de conserver dans l’historique l’information d’un retro-pédalage au sein du projet. À ça s’ajoute un autre argument : on s’autorise rarement des rebases et resets sur le tronc commun, car cela peut avoir plus facilement une incidence négative dans la collaboration avec les collègues, demandant nécessairement des synchronisations plus complexes qu’avec le revert.
Tu peux aussi regarder le programme de notre formation "Comprendre Git" ou nous poser tes questions sur notre forum discord.
Comment ça fonctionne ?
Rien de plus facile : tu passes la référence du commit à annuler !
Dans les interfaces graphiques qui font bien le boulot, en général un clic droit puis « annuler » fait la même chose.