- Qu’est-ce qu’un conflit de fusion Git ?
- Types de fusion
- Types de conflits de fusion Git
- Commandes pour résoudre les conflits de fusion Git
- Outils de fusion visuelle
- Comment résoudre un conflit de fusion Git
- Conclusion
Qu’est-ce qu’un conflit de fusion Git ?
Le système de contrôle de version Git est axé sur le travail en équipe et la contribution à des projets. Les développeurs travaillent généralement sur des branches isolées, et lorsqu’ils sont terminés, ils fusionnent les modifications avec la branche principale. Ce type de collaboration est très productive et efficace pour trouver les bugs. Parfois, plusieurs développeurs travaillent sur la même ligne de code, et lorsqu’ils essayent de fusionner les modifications, des conflits apparaissent.
Exemple simple de conflit Git
Le diagramme ci-dessus donne un exemple parfait de la manière dont une conflit de fusion typique dans Git se produit. Le dépôt principal contient un fichier avec le texte « HELLO, WORLD! ». Le nom d’utilisateur abid fait un fork du dépôt principal et change le texte en « HELLO, CAT! ». Pendant que abid effectue des changements, le dépôt principal original est également modifié en « HELLO, DOG! ». La fusion de ces branches déclenchera une erreur de conflit de fusion et stoppera le processus.
La commande `git merge` a principalement pour tâche de combiner deux branches et de résoudre automatiquement les conflits. Cependant, de temps à autre, des conflits apparaissent lorsque deux personnes ont modifié la même ligne de code ou supprimé des fichiers importants sur lesquels un autre développeur travaillait. Git marquera ces modifications et arrêtera le processus de fusion. Dans ce cas, le conflit n’a pas été résolu automatiquement ; le développeur doit plutôt effectuer des changements manuellement ou utiliser des outils pour résoudre le conflit.
Types de fusion
Git merge et rebase sont les deux façons d’intégrer des commits de la branche cible vers la branche source. De plus, Git merge effectue soit une fusion en avance rapide (fast-forward), soit une fusion sans avance rapide (no-fast-forward). Si la tête de la branche cible existe dans la branche source, alors par défaut, le type de fusion sera une avance rapide, et si elle est absente, alors une fusion sans avance rapide. Git rebase est un autre type de fusion qui réordonne l’historique des commits de la branche cible.
Fusion en avance rapide
Par défaut, Git merge utilise le relecteur rapide (fast-forward) pour intégrer les commits manquants dans la branche cible. Par exemple, il est utilisé pour mettre à jour la branche locale à partir d’un serveur distant en utilisant la commande pull. Le relecteur rapide ne provoque pas de conflits de fusion car Git ne l’appliquera pas si l’extrémité de la branche cible est absente dans la branche source.
Fusion sans fast-forward
Une fusion sans fast-forward est également appelée une fusion à trois voies ou véritable fusion. Elle crée un nouveau commit sur la branche cible en intégrant les modifications provenant de la source et de la branche cible. Les modifications sont mêlées après le dernier commit commun dans les deux branches. Dans notre cas, c’est après C. Ce type de fusion entraînera un conflit de fusion Git si la branche source est en conflit avec la branche cible. Dans le diagramme ci-dessus, le commit de fusion (X) est créé en intégrant la source et la branche cible, où K et E sont les parents du commit de fusion.
Rébase
Le référencement Git est légèrement différent des autres types. Il change la séquence de l’histoire des commits de la branche cible. Le référencement intègre la source de telle manière que la branche cible contient toutes les modifications de la source, suivies de tous les commits de la branche cible après le dernier commit commun. Dans notre cas, le dernier commit commun est C, tandis que D et E proviennent de la source. Le commit K* est le même que K avec un ID de commit différent. Au lieu de lier C, il se connectera à E. Semblable à une fusion sans fast-forward, si il y a des problèmes de compatible entre la source et la branche cible, Git soulèvera un problème pour résoudre le conflit avant de terminer la référencement.
Types de conflits de fusion Git.
Il existe deux types de conflits de fusion Git : à l’initialisation et pendant le processus de fusion – Atlassian. Dans cette section, nous apprendrons sur les deux types et les manières de résoudre chaque scénario.
Au début de la Fusion
La commande Git merge échouera au début si il y a des modifications dans le dossier de travail ou dans la zone d’enregistrement. Elle échoue au début pour éviter que les modifications ne soient écrasées par les commits de fusion entrants. Cela se produit en raison de conflits avec les modifications locales, pas avec d’autres branches ou développeurs. Pour stabiliser l’état local, vous pouvez utiliser des commandes telles que git stash
, git commit
, git checkout
, ou git reset
.
Pendant la Fusion
Un échec pendant la fusion signifie qu’il y a un conflit entre la branche source et la branche cible où plusieurs développeurs ont modifié le même fichier. Si la fusion automatique échoue, Git vous demandera de résoudre les problèmes manuellement. Vous pouvez également utiliser des outils tiers pour vous aider à visualiser et à intégrer les modifications.
Commandes pour résoudre les conflits de fusion Git
Dans cette section, nous apprendrons sur les diverses commandes native pour visualiser et résoudre les conflits de fusion Git.
Commandes Communes
La commande Git status est la plus fréquemment utilisée pour afficher l’état des fichiers modifiés, de la zone d’enregistrement et des commits. Pendant le processus de fusion, elle est utilisée pour identifier les fichiers conflits.
git status
Le journal Git avec l’argument –merge produit une liste de commits qui sont en conflit avec la branche source.
git log --merge
Par défaut, l’option git diff
affiche la différence entre les modifications non commitées et les commits précédents. Git diff est utilisé pour comparer des branches, des commits et des fichiers. C’est utile pour prévenir les futurs conflits de fusion.
git diff
Commandes en cas d’échec de fusion au départ
Checkout est utilisé pour annuler des modifications ou basculer vers une nouvelle ou ancienne branche.
git checkout
Git reset est utilisé pour réverter les modifications dans le répertoire de travail et la zone de préparation.
git reset --mixed
Commandes pour les conflits pendant la fusion
L’argument –abort arrêtera le processus de fusion et réinitialisera les modifications à leur état original avant le début de la fusion.
git merge --abort
Git reset est généralement utilisé pendant le processus de fusion pour réinitialiser les fichiers en conflit à leur état original.
git reset
Résoudre les conflits de fichier supprimé-modifié
Un conflit Git se produit si vous avez supprimé le fichier dans la branche courante et que quelqu’un d’autre l’a modifié dans une autre branche. Dans ce cas, vous pouvez soit ajouter un fichier et le commit,
git add <filename>
soit vous pouvez supprimer le fichier et le commit.
git rm <filename>
Outils de fusion visuels
Les outils de fusion sont des outils visuels faciles à utiliser pour identifier et résoudre tous types de conflits de fusion. Certains des outils supportent des capacités supplémentaires telles que la comparaison des modifications, les opérations Git et la gestion de projets et de dépôts. Il existe deux types d’outils de fusion Git : ceux basés sur la ligne de commande et ceux basés sur l’interface graphique. Les outils basés sur la ligne de commande s’ouvrent dans PowerShell ou Bash, et les outils basés sur l’interface graphique s’ouvrent dans un environnement à fenêtres.
Pour vérifier la liste des outils installés et valides, utilisez :
git mergetool --tool-help
Cette liste comprend tous les outils valides qui peuvent être installés et intégrés avec les commandes git.
Par exemple, vim et nvim sont installés par défaut, et si vous voulez voir la différence entre un fichier non committé et un commit précédent, tapez :
git difftool --tool=vimdiff3
L’outil vimdiff3 met en évidence les modifications et vous permet de comparer les commits dans la console.
Différence entre deux versions du même fichier dans Vimdiff3
Meld
Meld est un outil gratuit et open-source qui permet de résoudre les conflits de fusion à un niveau supérieur. Pour l’intégrer à Git, vous devez d’abord télécharger et installer le programme depuis le site officiel. Ensuite, ajoutez-le à la configuration globale afin que par défaut, Git lance Meld pour résoudre les conflits.
Les commandes de configuration ci-dessous ne sont valables que pour les utilisateurs Windows. La seule modification que vous devez faire est de changer le chemin du fichier installé de Meld pour Mac ou Linux.
git config --global merge.tool meld git config --global mergetool.meld.path "C:/Program Files (x86)/Meld/Meld.exe" git config --global diff.tool meld git config --global difftool.meld.path "C:/Program Files (x86)/Meld/Meld.exe"
Après avoir configuré les paramètres par défaut, vous pouvez taper git difftool
dans le répertoire local de Git pour lancer la version Windows de Meld, ou vous pouvez utiliser git mergetool
pour résoudre les conflits de fusion comme illustré ci-dessous.
Résoudre un Conflit de Fusion avec Meld
VSCode
VSCode offre la méthode la plus pratique et la plus populaire pour résoudre un conflit de fusion. Lorsque Git échoue à fusionner automatiquement des fichiers, VSCode met en évidence le code en conflit et vous offre quatre options : accepter les modifications actuelles, accepter les modifications entrantes, accepter les deux modifications et comparer les modifications. Vous pouvez utiliser ces options pour nettoyer votre fichier et résoudre tous les problèmes en suspens.
Résoudre un Conflit de Fusion avec VSCode
Si vous cherchez une solution complète pour vos opérations Git, essayez GitKraken. Il est livré avec un client gratuit, une extension VSCode, et offre un outil intégré pour résoudre les conflits de fusion.
Comment Résoudre un Conflit de Fusion Git
Dans cette section, nous allons apprendre à créer un conflit de fusion Git et ensuite le résoudre. Le tutoriel est divisé en deux parties. Dans la première partie, nous apprendrons à résoudre les conflits Git localement ; la deuxième partie concerne la résolution des conflits avec un serveur distant (GitHub).
Conflit de Fusion Local
Créer des conflits de fusion nous aidera à comprendre comment ces problèmes surviennent en premier lieu. Nous pourrons ensuite utiliser des méthodes créatives pour résoudre ces problèmes ou même les prévenir à l’avenir.
Nous allons maintenant créer un dépôt Git avec un seul fichier et créer notre premier commit pour commencer.
- Créez un dossier appelé datacamp.
- Changez de répertoire pour datacamp.
- Initialisez Git.
- Créez un fichier README.md avec le titre donné.
- Stadiez et committez les modifications dans un fichier.
mkdir datacamp cd datacamp git init echo "# How to Resolve Git Merge Conflict" > README.md git add README.md git commit -m "first commit" >>> [main (root-commit) 8199ea2] first commit >>> 1 file changed, 1 insertion(+) >>> create mode 100644 README.md
Ensuite, nous allons créer une nouvelle branche readme et changer le titre de “..Git Merge..” à “..Git..”. Ajoutez le fichier et créez le commit en utilisant l’argument -am.
git checkout -b readme echo "# How to Resolve Git Conflict" > README.md git commit -am "new branch conflict added" >>> [readme 155f694] new branch conflict added >>> 1 file changed, 1 insertion(+), 1 deletion(-)
Retournez à la branche principale et ajoutez une nouvelle ligne au fichier README.md en utilisant >>. En sauvegardant les modifications et créant des commits, nous avons réussi à former un conflit entre deux versions du même fichier.
git checkout main echo "New change in base branch" >> README.md git commit -am " a line added to base branch Readme file" >>> [main f1f1874] a line added to base branch Readme file >>> 1 file changed, 1 insertion(+)
Comme nous pouvons le voir, lors de la fusion de la branche readme, Git a affiché un message indiquant que la fusion automatique a échoué, et nous devons faire des modifications manuellement puis committer le résultat.
git merge readme >>> Auto-merging README.md >>> CONFLICT (content): Merge conflict in README.md >>> Automatic merge failed; fix conflicts and then commit the result.
Nous résoudrons manuellement le problème en ouvrant et en modifiant le fichier dans Notepad. L’image ci-dessous montre une flèche avec HEAD, un séparateur et une flèche dans une direction différente avec un readme. La partie HEAD affiche les modifications existantes dans le branche principale, et la partie readme est la branche que nous voulons fusionner, qui consiste en un en-tête différent.
Résolution d’un Conflit de Fusion Manuellement
Pour résoudre le problème, nous supprimerons la partie branche readme, les flèches et le séparateur. La version finale du fichier devrait apparaître propre, comme indiqué ci-dessous.
Conflit Résolu
Après avoir ajouté le fichier et créé un commit, le conflit de fusion sera résolu. C’est la méthode la plus commune et la plus simple pour résoudre les problèmes. Vous pouvez également utiliser un environnement de développement intégré (IDE) pour résoudre les problèmes plus rapidement.
git commit -am "conflict resolved in file README.md" >>> [main 9994a29] conflict resolved in file README.md
Conflit de Fusion à distance
Pour créer et résoudre des conflits de fusion à distance, nous devons créer un nouveau dépôt sur GitHub.
Création d’un Nouveau Dépôt sur GitHub
Ajoutez ensuite le nom de dépôt distant (origin) avec son adresse au dépôt et poussez toutes les modifications du dépôt local vers la branche principale distante en utilisant le dépôt upstream.
git remote add origin https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git git push --set-upstream origin main >>> Enumerating objects: 12, done. >>> Counting objects: 100% (12/12), done. >>> Delta compression using up to 4 threads >>> Compressing objects: 100% (6/6), done. >>> Writing objects: 100% (12/12), 998 bytes | 499.00 KiB/s, done. >>> Total 12 (delta 2), reused 0 (delta 0), pack-reused 0 >>> remote: Resolving deltas: 100% (2/2), done. >>> To https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git >>> * [new branch] main -> main >>> branch 'main' set up to track 'origin/main'.
Pour créer un conflit, nous devons apporter des modifications au fichier README.md distant et local. Vous pouvez utiliser l’éditeur de fichiers GitHub pour changer “…Git merge…” en “…Sit-Merge…” et ensuite valider les modifications.
Apporter des Modifications dans l’Éditeur GitHub
Ensuite, dans le dépôt local, modifiez le fichier README.md pour ajouter seulement un simple titre et validez les modifications.
echo "# How to Resolve Merge Conflicts in Git Tutorial" > README.md git commit -am "local branch changes in README.md" >>> [main c677a13] local branch changes in README.md >>> 1 file changed, 1 insertion(+), 4 deletions(-)
Finalement, poussez les modifications vers le serveur distant. Notez que Git a généré une erreur avec des indices sur la manière de résoudre le problème.
git push >>> To https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git >>> ! [rejected] main -> main (fetch first) >>> error: failed to push some refs to 'https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git' >>> hint: Updates were rejected because the remote contains work that you do >>> hint: not have locally. This is usually caused by another repository pushing >>> hint: to the same ref. You may want to first integrate the remote changes >>> hint: (e.g., 'git pull ...') before pushing again. >>> hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Nous suivrons l’indice le plus simple, qui consiste à récupérer le fichier depuis le serveur distant avant de le pousser.
La récupération du fichier a échoué en raison d’un conflit de fusion dans le fichier README.md. Nous pourrions le résoudre manuellement avec Notepad, mais cette fois-ci, nous utiliserons un outil visuel pour nous assister dans ce processus.
git pull >>> remote: Enumerating objects: 5, done. >>> remote: Counting objects: 100% (5/5), done. >>> remote: Compressing objects: 100% (2/2), done. >>> remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 >>> Unpacking objects: 100% (3/3), 681 bytes | 75.00 KiB/s, done. >>> From https://github.com/kingabzpro/DataCamp-Git-Merge-Guide >>> aaf149d..49b7d14 main -> origin/main >>> Auto-merging README.md >>> CONFLICT (content): Merge conflict in README.md >>> Automatic merge failed; fix conflicts and then commit the result.
L’outil de fusion Meld identifiera les fichiers en conflit et les affichera dans l’application Meld GUI.
git mergetool >>> Merging: >>> README.md >>> Normal merge conflict for 'README.md': >>> {local}: modified file >>> {remote}: modified file
Il y a trois colonnes : README_LOCAL_473.md, README.md, et README_LOCAL_473.md. Si vous pensez que les modifications distantes sont valides, cliquez sur la flèche noire dans la colonne distante ; et si vous souhaitez que les modifications locales persistent, cliquez sur la flèche noire dans la colonne locale. C’est aussi simple que ça.
Conflit Résolu avec l’Outil de Fusion Meld
Après avoir apporté des modifications, enregistrez le fichier et faites un commit. Comme vous pouvez le voir, pousser un fichier vers un serveur distant ne génère pas d’erreur de conflit de fusion.
git commit -am "remote main branch conflict resolved" git push >>> Enumerating objects: 16, done. >>> Counting objects: 100% (16/16), done. >>> Delta compression using up to 4 threads >>> Compressing objects: 100% (6/6), done. >>> Writing objects: 100% (10/10), 1.08 KiB | 550.00 KiB/s, done. >>> Total 10 (delta 2), reused 0 (delta 0), pack-reused 0 >>> remote: Resolving deltas: 100% (2/2), completed with 1 local object. >>> To https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git >>> 49b7d14..8f5c3aa main -> main
Nous avons résolu avec succès les conflits de fusion locaux et distants. Ces conflits sont traités quotidiennement par les data scientists et les ingénieurs en apprentissage automatique. Pour améliorer vos compétences en opérations Git, suivez un cours d’Introduction à Git.
Conclusion
Résoudre les conflits de fusion Git est une tâche complexe et très risquée car vous pouvez casser le logiciel en fusionnant du code défectueux. Les outils de fusion fournissent un environnement convivial avec une méthode plus sûre pour détecter et résoudre les conflits de fusion. Dans ce tutoriel, nous avons appris pourquoi les conflits Git surviennent et comment les résoudre. Nous avons également couvert différents types de fusion et de conflits, des commandes Git utiles et des outils visuels. Dans la section finale, nous avons créé un conflit de fusion et l’avons résolu dans un dépôt local et distant.
Si vous êtes nouveau sur Git et que vous voulez apprendre comment il fonctionne, alors lisez : Intro à Git et Tutoriel GitHub.
Source:
https://www.datacamp.com/tutorial/how-to-resolve-merge-conflicts-in-git-tutorial