Aller au contenu

Conflits de fusion

Les conflits de fusion surviennent lorsque plusieurs auteurs modifient le même contenu ou lorsqu'un développeur supprime un fichier pendant qu'un autre développeur y apportait des modifications. Pour résoudre ce problème, les développeurs travaillent dans des branches isolées. La commande git merge est responsable de la combinaison des branches isolées et de la résolution des modifications conflictuelles.

Git rend le processus de fusion plus simple que la plupart des systèmes de contrôle de version. Git peut intégrer automatiquement les nouvelles modifications dans de nombreux cas. Cependant, en cas de conflits, Git ne peut pas déterminer automatiquement quelle version est correcte. Il marque le fichier comme étant en conflit et arrête le processus de fusion.

mergeconflicts

Interruptions courantes de la fusion

Des erreurs peuvent survenir à deux moments : au début du processus de fusion ou pendant celui-ci. Notez qu'elles sont généralement causées par des modifications locales non validées plutôt que par des conflits de contenu réels.

Échec de la fusion au démarrage

Git échoue à démarrer une fusion car les modifications en attente dans le répertoire de travail ou la zone de staging du projet seraient écrasées par les commits en cours de fusion. Cela se produit en raison de modifications locales en attente. Pour reprendre le contrôle de l'état local, les commandes git stash, git checkout, git commit et git reset sont utilisées. Le message suivant s'affichera lorsqu'une erreur se produit au démarrage :

conflits git

bash
error: Your local changes to the following files would be overwritten by merge:

Échec pendant la fusion

L'échec pendant la fusion indique qu'il y a un conflit entre la branche locale actuelle et la branche qui est en cours de fusion. Le message suivant s'affichera lorsqu'une erreur se produit pendant la fusion :

échec pendant la fusion

bash
CONFLICT (content): Merge conflict in example.txt
Automatic merge failed; fix conflicts and then commit the result.

Création d'un conflit de fusion

Ici, nous allons vous montrer une simulation de l'apparition des conflits de fusion.

conflits de fusion

bash
mkdir test-dir
cd test-dir
git init .
echo "some content" > example.txt
git add example.txt
git commit -m "initial commit"
[master (root-commit) a45c22d] initial commit
1 file changed, 1 insertion(+)
create mode 100644 example.txt

Dans l'exemple donné, nous créons un nouveau répertoire nommé test-dir. Ensuite, nous créons un fichier texte example.txt avec du contenu et l'ajoutons au dépôt pour le valider. En résultat, nous avons un nouveau dépôt avec une branche master et le fichier example.txt. L'étape suivante consiste à créer une autre branche à utiliser comme fusion conflictuelle.

résolution des conflits

bash
git checkout -b branch_to_merge
echo "completely different content to merge later" > example.txt
git commit -m "edit the content of example.txt to make a conflict"
[branch_to_merge 4221135] edit the content of example.txt to make a conflict
1 file changed, 1 insertion(+), 1 deletion(-)

Dans l'exemple ci-dessus, nous créons et nous positionnons sur la branche branch_to_merge. Après l'avoir créée, nous remplaçons le contenu dans example.txt et validons le changement. Après avoir fait tout cela, le commit écrase le contenu de example.txt :

conflits de fusion git

bash
git checkout master
Switched to branch 'master'
echo "content to add" >> example.txt
git commit -m "added content to example.txt"
[master 11ab34b] added content to example.txt
1 file changed, 1 insertion(+)

Ces commandes basculent vers la branche master, ajoutent du contenu à example.txt, et valident le changement. Cela place le dépôt dans un état où la branche master et la branche branch_to_merge ont chacune un commit unique. L'étape finale consiste à exécuter la commande git merge, après quoi un conflit se produira :

git merge

bash
git merge branch_to_merge
Auto-merging example.txt
CONFLICT (content): Merge conflict in example.txt
Automatic merge failed; fix conflicts and then commit the result.

Identification des conflits de fusion

Comme nous l'avons déjà vu, Git affiche une sortie indiquant qu'un conflit est apparu. Exécutez la commande git status pour voir les chemins non fusionnés :

conflits git

bash
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 <file>..." to mark resolution)
both modified:   example.txt

Le fichier example.txt apparaît dans un état modifié. Exécutez la commande cat pour afficher le contenu du fichier example.txt. Nous pouvons voir ces marqueurs visuels :

résolution des conflits git

bash
<<<<<<< HEAD
=======
>>>>>>> branch_to_merge

Le marqueur ======= indique le centre du conflit. Le contenu entre les marqueurs <<<<<<< HEAD et ======= appartient à la branche actuelle (master) vers laquelle pointe la référence HEAD. Pour annuler complètement la fusion et revenir à l'état avant la fusion, exécutez git merge --abort. Pour en savoir plus sur les marqueurs visuels, consultez la page git merge.

Résolution des conflits de fusion

Pour résoudre un conflit de fusion, vous devez modifier le fichier concerné. Ouvrez le fichier example.txt dans un éditeur, supprimez les marqueurs de conflit et conservez les modifications souhaitées. Un fichier résolu pourrait ressembler à ceci :

conflits dans git

bash
some content to mess with
content to add

Exécutez la commande git add pour ajouter au staging le nouveau contenu de fusion. Ensuite, créez un nouveau commit pour terminer la fusion :

résolution des conflits dans git

bash
git add example.txt
git commit -m "the conflict in example.txt is merged and resolved"

Alternativement, vous pouvez utiliser git mergetool pour résoudre les conflits visuellement à l'aide d'un outil de comparaison configuré. Par exemple, exécutez git mergetool example.txt pour ouvrir l'outil pour un fichier spécifique.

OutilDescription
git statusAide à identifier les fichiers en conflit.
git mergetoolOuvre un outil de comparaison visuel pour résoudre les conflits de manière interactive.
git diffAffiche les différences entre les commits, les branches ou les fichiers pour aider à identifier les conflits potentiels avant la fusion.
git checkout --ours/--theirsRemplace le fichier en conflit par le contenu de la branche actuelle ou entrante.
git reset --mixedDésindexe les fichiers mais laisse le répertoire de travail inchangé.
git merge --abortAnnule la fusion en cours et restaure le répertoire de travail à l'état avant le début de la fusion.
git resetRéinitialise l'index pour qu'il corresponde à HEAD, aidant à désindexer les fichiers en conflit.

Practice

Quels sont les aspects de la gestion des conflits de fusion dans Git ?

Trouvez-vous cela utile?

Aperçu dual-run — comparez avec les routes Symfony en production.