Votre commit est fait, synchronisé avec votre remote et vous venez de vous rendre compte que votre code a introduit une anomalie dans le code, que faire maintenant ?

Je dirais que la première étape serait de mettre en place une stratégie de tests automatisés dans votre projet, mais c'est un autre débat, pour un autre article.

Pas de panique, Git vous donne évidemment la possibilité de revenir en arrière, sinon à quoi servirai un gestionnaire de versions de code après tout ?

Le problème est d'arriver à choisir la bonne solution parmi les multiples possibilités, je vais donc vous présenter deux méthodes : revert et reset qui ont toutes les deux leur mode de fonctionnement qui va influer sur l'état final de votre projet.

Mais en premier lieu il nous faut trouver le commit auquel nous voulons revenir, car ces deux méthodes ne permettent pas seulement de revenir au commit précédent, elles permettent de revenir à n'importe quel commit antérieur.

Cibler le commit désiré

Revert et reset utilisent le hash du commit cible pour effectuer leurs modifications, il vous faut donc récupérer ce hash au préalable. Pour se faire, rien de plus simple, il vous suffit d'utiliser la commande "git log" qui vous donne l'historique complet de votre branche actuelle.

$ git log

commit 1cea038e917dfac1031f41f2eb2134cc92c65b71 <<hash
Author: Nicolas Brondin-Bernard 
Date:   Tue Jan 12 00:15:56 2021 +0100

    [FEATURE] User - Auth

commit b0f28218b6a28b02b2fc86b223849fe81e5405ae
Author: Nicolas Brondin-Bernard 
Date:   Mon Dec 14 22:10:24 2020 +0100

    [FEATURE] Projects - List

commit ceeebc74d33733a1f76f8a2dae0a24166c01a21a
Author: Nicolas Brondin-Bernard 
Date:   Mon Sep 2 14:06:37 2019 +0200

    [INITIAL] Project based on React boilerplate

Comme ci-dessus, le hash est présent à côté du mot-clé "commit", vous pouvez alors le copier-coller pour la suite.

git revert

La première méthode est d'utiliser git revert pour annuler un ou plusieurs commit, tout en gardant un historique des modifications.

En effet, revert ne va pas simplement "effacer" les commits effectués après celui que vous ciblez, il va créer un nouveau commit contenant l'inverse de toutes les modifications effectuées jusqu'alors.

Imaginez que vous avez commit la création de 25 lignes de codes, en utilisant git revert, le gestionnaire de version va créer un commit dans lequel il supprime ces même 25 lignes, cela permet à la fois de revenir à l'état désiré du projet, tout en conservant un historique de ce qui a été modifié puis annulé.

Prenons l'exemple d'un historique Git comme suit :

o commit (hash aaa)
|
o commit (hash bbb)
|
o commit (hash ccc)

En effectuant la commande suivante :

$ git revert bbb

L'historique du projet sera alors :

o commit (hash aaa)
|
o commit (hash bbb)
|
o commit (hash ccc)
|
o commit revert (hash ddd, même état que bbb, annulation des modifications de ccc) 

Votre projet sera retourné à un état correct, et vous aurez donc l'historique des modifications (et de l'annulation) dans votre arbre de versions.

git reset

Avec cette méthode, l'historique de vos modifications et annulations ne seront pas conservées, votre projet sera réinitialisé dans l'état du commit sélectionné, et tous les commits postérieurs seront purement et simplement supprimés de l'arbre.

En reprenant la même base de projet que précédemment :

o commit (hash aaa)
|
o commit (hash bbb)
|
o commit (hash ccc)

En effectuant la commande suivante :

$ git reset bbb

L'historique du projet sera alors :

o commit (hash aaa)
|
o commit (hash bbb)

Ici votre projet aura retrouvé l'état initial du commit bbb et les modifications effectuées après ce commit ont toutes été annulées et ne sont plus visibles.

Attention néanmoins, si vous aviez déjà poussé votre commit ccc en remote, votre version locale va alors se retrouver en retard par rapport à la version distante et votre prochain push sera refusé. Pour régler ce problème vous pouvez indiquez à la version distante que vous désirez bel et bien écraser ces modifications en utilisant l'option "--force" :

$ git push origin --force

J'espère que cet article vous aura plu, et à bientôt sur le blog !


À propos de l'auteur

Hello, je suis Nicolas Brondin-Bernard, ingénieur web indépendant depuis 2015 passionné par le partage de d'expériences et de connaissances.

Aujourd'hui je suis aussi coach pour développeurs web juniors, tu peux me contacter sur nicolas@brondin.com, sur mon site ou devenir membre de ma newsletter pour ne jamais louper le meilleur article de la semaine et être tenu au courant de mes projets !


Photo par Thought Catalog sur Unsplash