Nous pouvons compromettre une application en fusionnant du code problématique, que ce soit à cause de l’intégration accidentelle de travail inachevé dans la branche principale ou en négligeant un bug critique qui a échappé aux tests automatisés.
Dans cet article, je vais vous guider à travers le processus d’utilisation de git revert
pour annuler en toute sécurité une fusion, en veillant à ce que l’historique des commits reste intact et que l’intégrité du projet soit préservée.
Comment git revert
Fonctionne
Nous pouvons penser à git revert
comme la version Git de la commande undo. Cependant, la commande git revert
ne supprime pas les commits ou ne saute pas à un état précédent de la branche. Au lieu de cela, elle crée un nouveau commit qui annule les modifications d’un commit spécifique.
La syntaxe pour révoquer un commit avec le hachage <commit_hash>
est :
git revert <commit_hash>
Nous pouvons lister les commits accompagnés de leurs identifiants de hachage en utilisant la commande git log
. La sortie de git log
énumère les commits du plus récent au plus ancien, comme ceci :
Pour exemple, pour révoquer le commit qui implémente la fonction de soustraction, nous utiliserions la commande :
git revert 7ba24a3e62d4d37182428ccfaa070baa222b1151
En utilisant git revert
, nous pouvons annuler les modifications d’un commit spécifique sans affecter l’historique des commits.
Notez que git revert
n’est pas magique, et en fonction de l’historique des commits, cela peut entraîner un conflit qui doit être résolu manuellement.
Avantages de git revert
par rapport aux modifications manuelles
Pourquoi git revert
est-il utile si nous devons peut-être résoudre un conflit manuellement ? Ne serait-il pas plus simple de simplement annuler les modifications manuellement ? Voici ses avantages :
- Préserve l’historique :
git revert
crée un nouveau commit qui annule les modifications d’un commit spécifique tout en preserving l’ensemble de l’historique des commits. Cela aide à maintenir une historique des modifications et des annulations transparente. - Annulation atomique : Il garantit que les annulations sont atomiques et cohérentes. Lorsque nous supprimons et committons des modifications manuellement, il y a un risque d’erreur humaine.
- Conscience des conflits : Il garantit que nous sommes avertis par des conflits s’il y a des intégrations ou des modifications dépendantes du commit original. Cela peut sembler inconvénient, mais cela protège contre les effets secondaires non intentionnels.
- Métadonnées : Le nouveau commit créé par git revert inclut des métadonnées et un message de commit qui décrit contextuellement ce qui a été annulé, aidant à la compréhension future. Sans
git revert
, ce contexte pourrait être perdu.
Annuler une Fusion dans Différentes Scénarios
Dans cette section, nous apprenons comment annuler une fusion. Pour l’exemple, nous supposons que nous fusionnons une branche nommée feature
dans la branche main
en exécutant la commande depuis la branche main
:
git merge feature
Ce que nous apprenons ici peut être appliqué à n’importe quelles deux branches en remplaçant les noms respectivement.
Annuler une fusion qui n’a pas de commit associé
La commande git merge
ne crée pas toujours un nouveau commit. Un commit est créé uniquement si la branche main
s’est écartée de la branche feature
. Puisque git revert
nécessite un commit pour fonctionner, nous ne pouvons pas l’utiliser dans ce cas.
Les branches main
et feature
divergent lorsque de nouveaux commits sont créés sur main
qui ne sont pas ancêtres de la branche feature
. En d’autres termes, de nouveaux commits ont été créés sur main
après que feature
ait été créée.
Si les branches ne se sont pas écartées, lorsque nous exécutons la commande git merge feature
sur la branche principale, Git utilisera un fast-forward pour fusionner. Cela signifie qu’il déplace le HEAD
de la branche main
vers le HEAD
de la branche feature
.
Nous pouvons observer que cela s’est produit en regardant le résultat de git merge
:
Pour annuler une telle fusion, nous avons seulement besoin de remettre le HEAD
de la branche main
à son emplacement précédent. Pour cela, nous :
- Identifions le
HEAD
précédent en utilisant la commandegit reflog
- Réinitialiser le
HEAD
à celui d’avant en utilisantgit reset --hard <previous_head>
, en remplaçant<previous_head>
par l’ancienHEAD
.
La sortie de git reflog
ressemblera à quelque chose comme cela :
Nous pouvons identifier l’ancien HEAD
en regardant la ligne qui dit “checkout: moving from feature to main” (elle écrit feature
et main
parce que ce sont les noms de nos branches).
Dans ce cas, l’ancien head est fe59838
. Pour ramener le HEAD
de la branche principale à celui-ci et annuler la fusion, nous utilisons alors la commande :
git reset --hard fe59838
Annuler une fusion qui a un commit associé
Si les branches main
et feature
se sont écartées,alors lors de la fusion de deux branches, un nouveau commit est créé, appelé commit de fusion.
Le commit de fusion applique les modifications d’une branche à une autre. Dans ce cas, les modifications dans feature
sont appliquées à la branche main
.
Pour annuler les modifications sur la branche main
, nous utilisons git revert
sur le commit de fusion. Cela créera un nouveau commit qui annule les modifications apportées à la branche main
par la fusion, restaurant ainsi l’état de la branche principale à ce qu’il était avant la fusion.
Premièrement, nous devons identifier le hachage du commit de fusion. Nous pouvons le faire en utilisant la commande git log
:
Parce que le commit de fusion a deux parents, la syntaxe de git revert
est légèrement différente. Nous devons utiliser l’option -m 1
pour spécifier que nous voulons révoquer les modifications par rapport à la branche main
:
git revert -m 1 b8dab2c8611e324ed0d273133987415350e6d10d
Résolution des conflits lors de la révocabilité d’un commit
Parfois, des conflits peuvent survenir lors de la révocabilité d’un commit, en particulier si le commit à révoquer entre en conflit avec des modifications ultérieures dans le codebase. Dans de tels cas:
- Git mettra en pause la révocabilité : nous devons résoudre manuellement les conflits. Git marquera les fichiers en conflit et exigera une intervention.
- Résoudre les conflits : nous ouvrons chaque fichier en conflit, résolvons les conflits marqués par Git, et enregistrons les modifications.
- Mettre les fichiers résolus en index :
git add <chemin-du-fichier>
- Continuer la révocabilité:
git revert --continue
Conclusion
Utiliser git revert
pour annuler les commits de fusion assure que chaque changement et correction est documenté au sein de l’historique des commits.
De plus, comprendre les scénarios appropriés pour appliquer git reset
par rapport à git revert
nous permet de prendre de meilleures décisions, surtout en considérant les flux de travail collaboratifs ou les changements locaux uniquement.
Vous pouvez en savoir plus sur ce sujet dans la section FAQ ci-dessous. Si vous souhaitez en apprendre davantage sur Git, je recommande ces ressources :