Aller au contenu
Développement medium
🔐 Alerte sécurité — Incident supply chain Trivy : lire mon analyse de l'attaque

Merge et résolution de conflits

6 min de lecture

git merge intègre le travail d’une branche dans une autre. Deux cas : soit Git avance simplement le pointeur (fast-forward), soit il crée un commit de fusion (3-way merge). Ce guide explique les deux mécanismes et vous montre comment résoudre les conflits quand ils surviennent.

Prérequis : Les branches Git en bref.

  • Distinguer fast-forward et merge à 3 sources et choisir selon le contexte
  • Résoudre un conflit de merge manuellement étape par étape
  • Utiliser --no-ff pour conserver un historique de branche explicite
  • Annuler un merge en cours avec --abort

Quand la branche cible n’a aucun nouveau commit depuis la création de la branche source, Git se contente d’avancer le pointeur. C’est un fast-forward :

Avant :
main
C1 ← C2 ← C3 ← C4 ← C5
feature ← HEAD
Après git switch main && git merge feature :
main ← HEAD
C1 ← C2 ← C3 ← C4 ← C5
feature

Pas de commit supplémentaire. Le pointeur main avance directement vers C5.

Fenêtre de terminal
git switch main
git merge feature

Le message Git indique Fast-forward pour confirmer ce mode.

Même en cas de fast-forward possible, vous pouvez forcer un commit de fusion pour garder une trace explicite dans l’historique :

Fenêtre de terminal
git merge --no-ff feature
main ← HEAD
C1 ← C2 ← C3 ← C4 ← C5 ← M1
\ /
C4 ← C5
feature

Quand les deux branches ont des commits que l’autre n’a pas, Git fait un 3-way merge : il compare trois versions (l’ancêtre commun, votre branche, l’autre branche) et crée un commit de fusion :

Avant :
C4 ← C5 (main)
/
C1 ← C2 ← C3
\
C6 ← C7 (feature)
Après git switch main && git merge feature :
C4 ← C5 ← M1 (main ← HEAD)
/ /
C1 ← C2 ← C3 /
\ /
C6 ← C7 (feature)

Le commit M1 a deux parents (C5 et C7). Git ouvre votre éditeur pour le message de commit (par défaut : Merge branch 'feature' into main).

Un conflit se produit quand les deux branches modifient les mêmes lignes du même fichier. Git ne peut pas deviner quelle version garder.

Imaginons que main et feature ont chacune modifié la ligne 5 de config.yaml :

Fenêtre de terminal
git switch main
git merge feature
# Auto-merging config.yaml
# CONFLICT (content): Merge conflict in config.yaml
# Automatic merge failed; fix conflicts and then commit the result.
  1. Identifiez les fichiers en conflit :

    Fenêtre de terminal
    git status

    Les fichiers en conflit apparaissent sous Unmerged paths.

  2. Ouvrez le fichier et repérez les marqueurs de conflit :

    port: 8080
    <<<<<<< HEAD
    timeout: 30
    =======
    timeout: 60
    >>>>>>> feature
    debug: false
    • <<<<<<< HEAD : version de votre branche actuelle (main)
    • ======= : séparateur
    • >>>>>>> feature : version de la branche mergée
  3. Choisissez la bonne version (ou combinez les deux). Supprimez tous les marqueurs :

    port: 8080
    timeout: 60
    debug: false
  4. Marquez le conflit comme résolu :

    Fenêtre de terminal
    git add config.yaml
  5. Finalisez le merge :

    Fenêtre de terminal
    git commit

    Git propose un message par défaut. Vous pouvez le modifier pour documenter la résolution.

Si le conflit est trop complexe ou que vous n’êtes pas prêt à le résoudre :

Fenêtre de terminal
git merge --abort

Le dépôt revient à l’état précédant le git merge. Aucune perte de données.

Pour les conflits complexes, un outil graphique facilite la résolution :

Fenêtre de terminal
git mergetool

Git lance l’outil configuré (par défaut vimdiff). Pour en configurer un autre :

Fenêtre de terminal
# VS Code
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'
# Meld (Linux)
git config --global merge.tool meld

Git utilise des stratégies pour fusionner automatiquement. En pratique, vous n’avez presque jamais besoin de les choisir manuellement :

StratégieQuand Git l’utiliseDescription
ortPar défaut (Git ≥ 2.34)Remplace recursive, plus rapide, même résultat
recursivePar défaut (Git < 2.34)Merge récursif 3-way classique
octopusMerge de 3+ branchesFusionne plusieurs branches d’un coup
oursGarder uniquement notre versionIgnore les modifications de l’autre branche

Pour forcer une stratégie (rare) :

Fenêtre de terminal
git merge -s ours feature
  1. Mergez souvent : plus les branches divergent, plus les conflits sont complexes
  2. Tirez main avant de merger : git switch main && git pull avant git merge feature
  3. Utilisez --no-ff en équipe pour garder un historique lisible
  4. Testez après le merge : un merge sans conflit ne garantit pas que le code fonctionne
SymptômeCause probableSolution
CONFLICT (content)Mêmes lignes modifiéesÉditez le fichier, supprimez les marqueurs, git add
Already up to dateRien à fusionnerLa branche est déjà intégrée dans HEAD
Not possible to fast-forward, abortinggit pull avec --ff-onlyUtilisez git pull --rebase ou git merge
Merge crée des doublonsHistorique déjà partagéVérifiez avec git log --oneline --graph avant le merge
  • Fast-forward : Git avance le pointeur, pas de commit de merge
  • 3-way merge : Git crée un commit avec deux parents
  • --no-ff force un commit de merge même quand le fast-forward est possible
  • Les marqueurs de conflit (<<<<<<<, =======, >>>>>>>) délimitent les versions en conflit
  • git merge --abort annule un merge en cours sans perte de données

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn