Corrigez vos erreurs en local et à distance
La journée a été difficile et par mégarde vous avez pushé des fichiers erronés.
Le problème, c'est que cette erreur concerne aussi les personnes avec qui vous travaillez sur le projet.
Quelle est la première chose à faire dans ce cas-là ?
Prévenir vos collaborateurs, bien sûr !! Mais Git a tout de même la solution à votre problème.
Il est possible d'annuler son commit public avec la commande git revert. L'opération revert annule un commit en créant un nouveau commit. C'est une méthode sûre pour annuler des changements, car elle ne risque pas de réécrire l'historique du commit.
git revert HEAD^
Nous avons maintenant reverté notre dernier commit public et cela a créé un nouveau commit d'annulation. Cette commande n'a donc aucun impact sur l'historique ! Par conséquent, il vaut mieux utiliser git revert
pour annuler des changements apportés à une branche publique, et git reset
pour faire de même, mais sur une branche privée.
Utilisez git reset
Imaginez que votre client vous demande une nouvelle fonctionnalité ; vous travaillez dessus toute la journée et le lendemain, finalement, il change d'avis. Catastrophe !
Vous avez perdu une journée à développer une fonctionnalité pour rien, mais en plus il faut que vous trouviez le moyen de revenir en arrière ! Heureusement, notre ami Git arrive à notre rescousse avec la commande git reset
!
Les trois types de réinitialisation de Git
La commande git reset
est un outil complexe et polyvalent pour annuler les changements. Elle peut être appelée de trois façons différentes, qui correspondent aux arguments de ligne de commande --soft, --mixed et --hard.
Nous allons commencer par reset --hard
.
Exécutez la commande :
git reset notreCommitCible --hard
Cette commande permet de revenir à n'importe quel commit mais en oubliant absolument tout ce qu'il s'est passé après ! Quand je dis tout, c'est TOUT ! Que vous ayez fait des modifications après ou d'autres commits, tout sera effacé ! C'est pourquoi il est extrêmement important de revérifier plusieurs fois avant de la lancer, vous pourriez perdre toutes vos modifications si elle est mal faite.
Cette utilisation de git reset
constitue une manière simple d'annuler des changements qui n'ont pas encore été partagés. Cette commande est incontournable lorsque vous commencez à travailler sur une fonctionnalité, que vous vous êtes trompé et que vous voulez recommencer de zéro. Le git reset --mixed
va permettre de revenir juste après votre dernier commit ou le commit spécifié, sans supprimer vos modifications en cours. Il permet aussi, dans le cas de fichiers indexés mais pas encore commités, de désindexer les fichiers.
git reset HEAD~
Si rien n'est spécifié après git reset
, par défaut il exécutera un git reset --mixed HEAD~
.
C’est un peu comme votre ombre : elle vous suit où que vous alliez ! Par défaut, HEAD pointe sur la branche courante, main/master, et peut être déplacé vers une autre branche ou un autre commit.
Nous avons enfin git reset --soft
. Cette commande permet de se placer sur un commit spécifique afin de voir le code à un instant donné, ou de créer une branche partant d'un ancien commit. Elle ne supprime aucun fichier, aucun commit, et ne crée pas de HEAD détaché.
Oups, j'ai des conflits !
Nous avons vu dans la deuxième partie de ce cours comment fusionner des branches, en utilisant un exemple assez simple où tout s'est bien terminé. Malheureusement, il arrive parfois, même souvent, que cela ne se passe pas aussi bien, et que des conflits apparaissent.
Si nous reprenons notre exemple de début de cours, vous avez travaillé sur la branche “ameliorationCagnotte” alors que des fichiers correspondant à l'amélioration de la fonctionnalité "cagnotte" existent déjà dans la branche principale, et que vous modifiez des lignes déjà en place.
Vous avez modifié du code pour afficher le message "Une super cagnotte !" alors qu'était déjà en place le message "Une cagnotte". Lorsque vous allez fusionner les deux branches, les choses ne vont donc pas très bien se passer :
git checkout main git merge ameliorationCagnotte Auto-merging cagnotte.php CONFLICT (content): merge conflict in cagnotte.php Automatic merge failed; fix conflicts and then commit the result
Git va voir que sur la même ligne on essaie de fusionner deux choses différentes. Il ne va pas pouvoir deviner laquelle prendre, la ligne "Une cagnotte", ou bien "Une super cagnotte !" ? Il est fort mais pas devin ! Git va donc afficher un conflit sur le fichier cagnotte.php et arrêtera le processus de fusion ou merge. Ce conflit, vous allez devoir le résoudre en ouvrant le fichier avec votre éditeur habituel :
<<<<<<< HEAD Une cagnotte ======= Une super cagnotte ! >>>>>>> ameliorationCagnotte
Maintenant, réglez les conflits en comparant les deux lignes et en choisissant quelle modification vous voulez garder. Ici, il faut garder "Une super cagnotte !", on va donc supprimer les autres lignes et ne garder que celle-ci :
Une super cagnotte !
Maintenant que vous avez résolu le conflit, il vous reste à le dire à Git !
git add cagnotte.php git commit
Git va détecter que vous avez résolu les conflits et va vous proposer un message de commit. Vous pouvez bien entendu le modifier.
J’ai ajouté le mauvais fichier au commit
Ralalala ! Décidément vous en faites des bêtises ! Alors comme cela, vous avez fait un commit mais un fichier s'est glissé par "erreur". Ne vous inquiétez pas, avec Git nous avons une super fonction qui va remonter le temps. La commande git revert vous permet de revenir à l'état précédent, tout en faisant un deuxième commit. Au lieu de supprimer le commit de l'historique du projet, elle détermine comment annuler les changements introduits par le commit et ajoute un nouveau commit avec le contenu ainsi obtenu. Vous allez donc revenir à l'état précédent mais avec un nouveau commit. Ainsi, Git ne perd pas l'historique, lequel est important pour l'intégrité de votre historique de révision et pour une collaboration fiable.
Quelle est la différence entre git reset et git revert ?
git reset
va revenir à l'état précédent sans créer un nouveau commit, alors que git revert
va créer un nouveau commit.
Essayons cette super commande en faisant un premier commit que nous allons finalement ne plus vouloir. Une fois votre commit fait, écrivez la commande suivante :
git revert HEAD
Une fois votre commit "annulé", vous pouvez enlever votre fichier et réaliser de nouveau votre commit.
En résumé
git revert HEAD^ permet d'annuler un commit en créant un nouveau commit.
git reset est une commande puissante. Elle peut être appliquée de 3 façons différentes (--soft; --mixed; --hard).
La commande git merge produit un conflit si une même ligne a été modifiée plusieurs fois. Dans ce cas, il faut indiquer à Git quelle ligne conserver.
git reset permet de revenir à l'état précédent sans créer un nouveau commit.
git revert permet de revenir à l'état précédent en créant un nouveau commit.
Voyons comment corriger un commit raté dans le prochain chapitre !