Débuter avec Git partie 6 : une fusion de branches échoue
Aujourd’hui pour continuer cette série d’articles sur débuter avec Git, nous allons démystifier une situation qui provoque un stress important auprès des nouveaux utilisateurs de Git : lorsqu’une fusion de branches échoue.
Il arrive malheureusement qu’une fusion de branches échoue. Ce cas se présente surtout dans l’utilisation collaborative de Git, où différentes personnes interviennent en même temps sur le code.
En effet Git est un outil très bien conçu, mais il ne prendra jamais une décision à la place de ses utilisateurs. Or, si la même partie du code est modifiée par deux utilisateurs différents, qui a raison ? Qui a tort ? Qui Git doit-il croire ?
Mise en place du conflit de fusion
Nous allons tout d’abord créer un fichier README.md dans un nouveau dépôt Git avec un titre et deux sections.
$ mkdir fusion-echoue $ cd fusion-echoue/ $ git init . Initialized empty Git repository in /tmp/fusion-echoue/.git/ $ vi README.md $ cat README.md # README ## installation apt-get install whatever ## use whatever param1 param3 param3 $ git add README.md && git commit README.md -m "add README.md" add README.md 1 file changed, 9 insertions(+) create mode 100644 README.md
Nous créons maintenant une branche dédiée à l’ajout d’une nouvelle section pour indiquer la licence du projet dans le README.md.
$ git checkout -b new-license Switched to a new branch 'new-license' $ vi README.md $ git commit README.md -m "license section" license section 1 file changed, 3 insertions(+)
Jetons un oeil à l’état actuel de notre fichier sur a branche new-license:
# README ## installation apt-get install whatever ## use whatever param1 param3 param3 # license BSD
Un code, deux choix différents
Pendant ce temps, dans la branche master, un développeur semble avoir fait un choix différent au niveau de la licence.
git checkout master Switched to branch 'master' $ vi README.md $ git commit README.md -m "license section - use gpl" [master bf15ff3] license section - use gpl 1 file changed, 3 insertions(+)
Voici l’état actuel du fichier sur la branche master.
# README ## installation apt-get install whatever ## use whatever param1 param3 param3 # license GPLv3
Une fusion destinée à échouer
L’événement-déclencheur du drame va être la volonté de supprimer la branche créée auparavant et de réintégrer son code dans master. Pour cela, rien de plus simple, nous utilisons git merge comme vu dans l’article précédent.
$ git merge new-license Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.
Oups, le CONFLICT en majuscule nous annonce que Git a rencontré un conflit en tentant de fusionner la branche new-license dans la branche master.
La dernière phrase est très claire : résoudre les conflits est un préalable indispensable à continuer la fusion.
Résoudre le conflit… ou pas
Si vous avez déjà rencontré ce problème en utilisant Git, vous avez sûrement éprouvé ce sentiment : la grosse panique. Vous vous voyez déjà accuser des pires manipulations par vos collègues et de casser l’outil de travail commun. DU CALME, PAS DU TOUT.
Avant de céder à la panique, repassons la commande git status.
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add …" to mark resolution)
both modified: README.md
La sortie de la commande est très claire : un simple git merge –abort vous fera revenir à la situation précédant le git merge. Voyons cela.
$ git merge --abort $ git status On branch master nothing to commit, working tree clean
Voilà, vous pouvez vous détendre et ranger votre lette de démission. Tout va bien se passer.
Résouder le conflit
Nous allons maintenant tenter de réellement résoudre notre conflit. Avant cela, nous devons prendre conscience de la tâche qui nous attend.
$ git merge new-license
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add …" to mark resolution)
both modified: README.md
La sortie de la commande git status nous indique qu’un seul fichier pose problème par la mention sur la dernière ligne both modified: README.md.
Ce n’est pas nos quelques lignes dans le README.md qui vont nous décourager. Jetons donc un oeil au fichier en question.
$ cat README.md # README ## installation apt-get install whatever ## use whatever param1 param2 param3 ## license <<<<<<< HEAD GPLv3 ======= BSD >>>>>>> new-license
Surprise, Git nous a maché le travail.
Dans la section license du fichier, nous voyons que la partie entre <<<<<<< HEAD et ======= provient de HEAD, qui pointe actuellement sur master, donc le code provenant de master. Vous avez oublié ce qu’est HEAD ? On en parle dans cet article.
À l’opposé, la partie entre ======= et >>>>>>> new-license provient donc de la branche new-license. C’est maintenant à vous de jouer et de faire un choix, Git ne le fera pas à votre place, une décision humaine est attendue.
Après consultation avec vos collègues, vous choisissez la licence GPLv3. Vous allez donc éditer le code de la section license pour ne laisser que la partie suivante :
## license GPLv3
La commande git status précédente nous indiquait la marche à suivre une fois le fichier édité.
Unmerged paths:
(use "git add …" to mark resolution)
both modified: README.md
Nous suivons donc ces instructions à la lettre.
$ git add README.md $ git status On branch master All conflicts fixed but you are still merging. (use "git commit" to conclude merge)
Le conflit est résolu. Nous allons maintenant utiliser git commit pour terminer la fusion.
$ git commit -a -m "use GPLv3 license. merge from new-license branch"
Si vous n’utilisez que la commande git commit sans argument, votre éditeur de texte s’ouvre et propose d’enregistrer le message de commit suivant :
Merge branch 'new-license'
Conclusion
Nous avons brilliamment résolu notre premier conflit de fusion entre deux branches. Il était franchement facile à régler, mais il nous a permis de détailler toutes les étapes nécessaires. Bien évidemment nous pouvons avoir des conflits bien plus sévères à régler, mais nous avons vu comment interrompre une fusion, ce qui nous aidera quoiqu’il arrive à revenir à un état stable du dépôt.
S’engager dans une fusion complexe réclame un très bonne connaissance du code manipulé et de ce qu’on fait vos collègues, pour ne pas écraser du code utile par inadvertance.
Me suivre sur les réseaux sociaux
N’hésitez pas à me suivre directement sur les différents sociaux pour suivre au jour le jour mes différentes projets dans le Logiciel Libre :
- Mastodon : @carlchenet
- Diaspora : @carlchenet
- Twitter : @carl_chenet
Suivre l’actualité du Logiciel Libre et Open Source francophone
Abonnez-vous au Courrier du hacker, une newsletter hebdomadaire résumant le meilleur de l’actualité francophone du Logiciel Libre et Open Source. Déjà plus de 90 numéros et 2000 abonnés.
The post Débuter avec Git partie 6 : une fusion de branches échoue appeared first on Carl Chenet's Blog.