Par Anonyme (non vérifié) , 29 avril 2026

Introduction

Git a deux résultats de merge fondamentalement différents : fast-forward, où la pointe d'une branche est simplement déplacée, et trois-voies, où un nouveau commit avec deux parents est créé. Le choix dépend de si les branches ont divergé.

Fast-forward

Si la pointe de main est un ancêtre de feature, aucun vrai merge n'est nécessaire. Git fait simplement avancer main :

      A---B---C   feature
     /
main

# après git merge feature
A---B---C   main, feature

Commande :

git switch main
git merge feature

Pour forcer un vrai merge commit même quand un fast-forward est possible :

git merge --no-ff feature

Merge trois-voies

Quand les deux branches ont divergé, Git trouve la base de merge (l'ancêtre commun le plus récent) et combine les changements des deux côtés :

      A---B---C   feature
     /
A---D---E   main

# après git merge feature
A---D---E---M   main
     \     /
      B---C   feature

La stratégie de merge par défaut de Git depuis 2.33 est ort ; avant c'était recursive. Les deux calculent un merge trois-voies par fichier en utilisant la base de merge.

Inspecter

git merge-base main feature
git log --oneline --graph --all
git show --stat HEAD          # voir le merge commit

Stratégies et options

git merge -X ours feature        # préférer notre côté en cas de conflit
git merge -X theirs feature      # préférer leur côté
git merge -X ignore-space-change feature
git merge --squash feature       # appliquer les changements sans merge commit

--squash crée un commit unique contenant tous les changements de feature, sans lien parent vers elle. Utile pour un historique propre mais perd le détail par commit.

Annuler et défaire

git merge --abort                # en plein merge, retour à l'état pré-merge
git reset --hard ORIG_HEAD       # après un merge terminé, l'annuler

Configurer la politique fast-forward

git config --global merge.ff false      # toujours créer un merge commit
git config --global merge.ff only      # seulement fast-forward, refuser sinon
git config --global pull.ff only       # idem pour les pulls

Pilotes de merge et attributs

Certains fichiers se mergent mal avec un trois-voies textuel (lockfiles générés par machine, documentation générée). Configurez un pilote de merge personnalisé via .gitattributes et git config :

# .gitattributes
package-lock.json merge=ours
Gemfile.lock merge=union
git config merge.ours.driver true
git config merge.union.name "Line union merge"
git config merge.union.driver "git merge-file --union %A %O %B"

La stratégie union intégrée garde les deux côtés ; ours choisit toujours notre version ; les pilotes personnalisés peuvent exécuter n'importe quel programme. À utiliser avec parcimonie ; un comportement de merge surprenant déroute les reviewers.

Erreurs fréquentes

Croire que le fast-forward est en quelque sorte spécial ou risqué ; il ne l'est pas, c'est juste un déplacement de pointeur. Utiliser --no-ff sur chaque merge dans un projet à évolution rapide, polluant l'historique avec des merge commits vides. Utiliser -X ours alors que vous vouliez --strategy=ours (qui abandonne entièrement l'autre côté) ou vice versa. Enfin, éditer manuellement le message de merge commit après coup et casser la formulation standardisée « Merge branch 'X' » sur laquelle s'appuient les outils ; si vous devez éditer, faites-le avant git commit.