Aller au contenu

git merge

Définition

La commande git merge intègre des lignes de développement indépendantes dans une seule branche. Elle fonctionne conjointement avec git checkout pour sélectionner la branche actuelle et git branch avec le drapeau -d pour supprimer les branches obsolètes. Consultez ces commandes dans nos chapitres précédents.

Fonctionnement

L'utilisation principale de git merge est de combiner deux branches. Elle est également utilisée pour intégrer plusieurs commits d'une branche dans une autre. Dans l'illustration suivante, git merge prend les sommets de deux branches et trouve un commit ancêtre commun entre elles. Le commit de base commun est utilisé pour créer un nouveau commit de fusion qui combine les modifications des deux branches. Ici, nous avons deux branches : master et stage. Nous devons fusionner la branche stage dans la branche master.

gitmerge

Les commits de fusion sont uniques car ils possèdent deux commits parents. Git combine automatiquement des historiques distincts lors de la création d'un nouveau commit de fusion. Cependant, si les deux branches modifient les mêmes lignes, Git ne peut pas les combiner automatiquement, ce qui entraîne un conflit de fusion.

gitmerge1

Processus de fusion

Avant de commencer le processus de fusion, suivez ces étapes :

  • Assurez-vous d'être sur la bonne branche de réception. Exécutez git checkout <branche de réception> pour y basculer.
  • Mettez à jour la branche cible avec les dernières modifications distantes. Exécutez git pull pour récupérer et intégrer les derniers commits distants.
  • La dernière étape consiste à exécuter git merge <nom de la branche>, qui spécifie la branche à fusionner dans la branche de réception.

Fusion en avant rapide

Une fusion en avant rapide (fast-forward) se produit lorsque le chemin de la branche actuelle vers la branche cible est linéaire. La fusion en avant rapide combine les historiques, car tous les commits accessibles depuis la branche cible sont disponibles via la branche actuelle. Voici un exemple de fusion en avant rapide :

gitmerge2

Lorsque les deux historiques divergent, Git utilise la fusion en 3 voies (3-way merge) comme alternative. La fusion en 3 voies utilise un commit dédié pour combiner deux historiques.

gitmerge3

Les fusions en avant rapide sont généralement utilisées pour de petites fonctionnalités ou des corrections de bugs, tandis que les fusions en 3 voies sont utilisées pour intégrer des fonctionnalités à long terme. Les exemples suivants utilisent une fusion en avant rapide :

git merge

bash
# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Merge in the stage branch
git checkout master
git merge stage
git branch -d stage

Nous exécutons git branch -d pour supprimer la branche stage, car stage est désormais accessible depuis la branche master.

La commande git merge avec l'option --no-ff est utilisée si vous avez besoin d'un commit de fusion lors d'une fusion en avant rapide pour fusionner la branche spécifiée dans la branche actuelle, générant toujours un commit de fusion (même dans le cas d'une fusion en avant rapide) :

git merge --no-ff

bash
git merge --no-ff <branch>

Fusion en 3 voies

Ce scénario nécessite une fusion en 3 voies lorsque la branche master progresse tandis que la branche stage est encore en développement. Cela est utilisé lorsque les membres de l'équipe travaillent simultanément sur une grande fonctionnalité :

the git merge command

bash
# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Develop the master branch
git checkout master
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to master"
# Merge in the stage branch
git merge stage
git branch -d stage

Dans l'exemple ci-dessus, stage représenterait une fonctionnalité plus importante prenant beaucoup de temps à développer, c'est pourquoi nous utilisons une fusion en 3 voies. Si votre fonctionnalité est petite, il vaut mieux utiliser une fusion en avant rapide pour éviter que des commits inutiles n'encombrent l'historique du projet.

Résolution des conflits

Lors de la fusion de deux branches, si la même partie du même fichier est modifiée, des conflits de fusion se produisent car Git ne peut pas déterminer quelle version utiliser. Lorsque cela se produit, Git s'arrête avant de créer le commit de fusion pour vous permettre de résoudre le conflit. Le processus de fusion de Git utilise un flux de travail modifier/ajouter/commit pour résoudre les conflits de fusion. Lorsqu'un conflit survient, l'exécution de git status affichera les fichiers qui doivent être résolus. L'image suivante apparaîtra lorsque les mêmes parties du fichier example.txt auront été modifiées :

git status

bash
On branch master
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: example.txt

Si vous décidez de ne pas poursuivre la fusion, vous pouvez l'annuler à tout moment en exécutant git merge --abort.

Présentation des conflits

En cas de conflit, Git modifie le contenu des fichiers concernés avec des marques visuelles de part et d'autre du contenu en conflit. Les conflits de fusion ne se produisent que dans le cas d'une fusion en 3 voies.

Les marqueurs principaux sont <<<<<<<, ======= et >>>>>>>. Ils vous aident à localiser les sections en conflit dans vos fichiers.

git conflicts

bash
here is some content not affected by the conflict
<<<<<<< master
this is conflicted text from master
=======
this is conflicted text from stage branch
>>>>>>> stage

Après avoir résolu les conflits, exécutez git add <fichier> sur le fichier en conflit pour le marquer comme résolu. Ensuite, exécutez git commit pour créer le commit de fusion.

Pratique

Quelles sont les fonctionnalités et processus clés impliqués dans la commande 'git merge' ?

Trouvez-vous cela utile?

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