Comparaison

Git merge ou rebase : quelle stratégie choisir pour votre équipe

Mis à jour: · Skillaria.Top

Merge et rebase intègrent tous deux les changements d'une branche, mais traitent l'historique différemment : merge le conserve tel quel et ajoute un commit de fusion, rebase réécrit vos commits sur une nouvelle base et rend l'historique linéaire. Règle pratique : rebase pour ranger vos commits non publiés, merge pour intégrer un travail terminé dans les branches partagées.

En bref : la différence entre merge et rebase

Le débat « git merge ou rebase » ne porte pas vraiment sur la meilleure commande, mais sur l'historique de projet que vous voulez lire. Les deux aboutissent au même code final. Ce qui change, c'est le chemin enregistré dans le journal.

  • Merge relie deux lignes d'historique et consigne honnêtement que le travail s'est fait en parallèle. Les commits existants restent intacts, un commit de merge à deux parents est ajouté.
  • Rebase réécrit vos commits comme si vous aviez commencé à partir de la version la plus récente de la branche de base. L'historique devient une ligne droite, mais les commits reçoivent de nouveaux hashes.

La mécanique de chaque commande — options, résolution des conflits, mode interactif — est détaillée dans des articles dédiés. Ici, on parle uniquement du choix de stratégie.

À quoi ressemble l'historique dans les deux cas

Situation de départ : vous avez créé feature, fait deux commits, et pendant ce temps deux commits d'autres personnes sont arrivés sur main.

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

Après git merge feature sur main :

          D---E
         /     \
A---B---C---F---G---M  main

Après git rebase main sur feature puis avance rapide de main :

A---B---C---F---G---D'---E'   main

Dans le premier cas, l'historique montre que la fonctionnalité a été développée en parallèle et à quel moment elle a été intégrée. Dans le second, l'historique se lit comme un récit séquentiel, mais la trace du travail parallèle a disparu : D' et E' sont de nouveaux commits créés au moment du rebase.

Tableau comparatif merge vs rebase

Critèregit mergegit rebase
Commits existantsInchangésRecréés avec de nouveaux hashes
Forme de l'historiqueGraphe ramifié avec commits de mergeLinéaire
Sûreté sur les branches partagéesToujours sûrDangereux pour les commits publiés
Force push nécessaireNonOui, si la branche est déjà sur le serveur
ConflitsRésolus une seule fois, dans le commit de mergePeuvent surgir sur chaque commit rejoué
Contexte « d'où ça vient »ConservéPerdu
Annuler une fonctionnalité entièreUn seul git revert -m 1 du commit de mergeRevert de chaque commit ou d'une plage
Confort avec git bisect et git logGraphe plus difficile à lirePlus simple : une seule ligne droite
Courbe d'apprentissageFaiblePlus élevée, il faut comprendre la réécriture d'historique
Nettoyage des commits (squash, reword)Seulement --squash en blocSouple via rebase -i

Avantages et inconvénients de merge

Avantages

  • Ne détruit pas l'historique. Tout ce qui a été publié reste en place. Vos collègues n'auront rien à réparer après votre opération.
  • Le conflit se résout une seule fois. Même avec 30 commits dans la branche, vous traitez l'état final et non chaque étape.
  • Le contexte est préservé. Le commit de merge montre quand chaque tâche est arrivée dans la branche principale, et on peut facilement l'annuler en bloc.

Inconvénients

  • Un graphe bruyant. Avec des synchronisations fréquentes, l'historique se couvre de commits « Merge branch 'main' into feature » et git log --graph se transforme en plan de gare de triage.
  • Les commits brouillons atterrissent dans l'historique. « wip », « fix », « encore un fix » restent pour toujours dans la branche principale si on ne les écrase pas.

Avantages et inconvénients de rebase

Avantages

  • Un historique linéaire et lisible. Chaque commit est à sa place, git log se lit comme une liste de changements et git bisect trouve plus facilement le commit fautif.
  • La possibilité de remettre de l'ordre dans les commits avant la revue : les fusionner, les renommer, les réordonner.
  • Pas de commits de merge techniques issus de la synchronisation avec la branche principale.

Inconvénients

  • Réécrit l'historique. Rebaser une branche partagée déjà publiée casse le travail de tous ceux qui l'ont récupérée.
  • Exige un force push pour les branches présentes sur le serveur, donc de la discipline et --force-with-lease.
  • Conflits répétés. Une même zone de code peut entrer en conflit sur plusieurs commits d'affilée.
  • Les commits intermédiaires peuvent ne plus compiler. Après le déplacement sur la nouvelle base, personne n'a testé les anciens commits dans le nouvel environnement.

Quand utiliser merge ou rebase

Rebase pour votre travail local

Vous mettez à jour votre branche avant de pousser : git pull --rebase. Vous préparez la branche pour la revue et voulez supprimer les commits brouillons : git rebase -i. Votre branche de fonctionnalité personnelle a pris du retard sur main : git rebase origin/main. Dans tous ces cas, vous réécrivez des commits que vous seul avez vus (ou qui n'appartiennent qu'à vous).

Merge pour les branches partagées et l'intégration

Une fonctionnalité terminée est intégrée dans main ou develop. Plusieurs personnes travaillent sur la branche. Il faut réintégrer une branche de release dans la branche principale. Ici, il est essentiel de ne pas toucher aux commits déjà publiés, et merge est la seule option correcte.

La règle simple

Si les commits n'existent que chez vous, rebase est permis. Si quelqu'un les a déjà récupérés, uniquement merge.

Workflows types pour une équipe

WorkflowFonctionnementPour qui
Merge uniquementLes fonctionnalités sont intégrées avec --no-ff, la synchronisation se fait avec git merge mainDébutants avec Git, équipes qui tiennent à une chronologie complète et à des retours arrière simples
Rebase + mergeLa branche est rebasée sur main avant intégration, puis commit de merge avec --no-ffÉquipes qui veulent à la fois un historique propre et des frontières de fonctionnalités visibles
Rebase + fast-forwardLa branche est rebasée puis intégrée en avance rapide, l'historique est entièrement linéairePetites équipes aux commits soignés et atomiques
Squash mergeChaque pull request devient un seul commit sur mainÉquipes aux tâches courtes, où l'historique détaillé de la branche n'est pas utile

Sur GitHub et GitLab, ces workflows correspondent aux boutons « Create a merge commit », « Rebase and merge » et « Squash and merge ». Mieux vaut n'autoriser que l'option retenue dans les paramètres du dépôt, pour que l'historique ne devienne pas un mélange de styles.

Les réglages qui verrouillent le choix

# pull sans commits de merge superflus
git config --global pull.rebase true

# ou : pull en avance rapide uniquement, sinon erreur — à vous de décider
git config --global pull.ff only

# toujours un commit de merge lors de l'intégration des fonctionnalités
git config --global merge.ff false

Attention à merge.ff false : il s'applique aussi à git pull en mode merge. Beaucoup préfèrent ne pas le définir globalement et écrire explicitement --no-ff lors de l'intégration d'une fonctionnalité.

Exemple : une même tâche dans les deux styles

Prenons un scénario concret. Vous développez pendant trois jours une fonctionnalité de paiement dans la branche feature/payment, et pendant ce temps cinq autres tâches ont été intégrées dans main. Avant d'ouvrir la pull request, il faut récupérer le main à jour et vérifier que tout fonctionne.

Version avec merge

git switch feature/payment
git fetch origin
git merge origin/main
# conflits résolus une seule fois, git add, git commit
git push

La branche a reçu un commit « Merge remote-tracking branch 'origin/main' into feature/payment ». Le push est normal, les collègues qui suivaient la branche ne remarquent rien. Si vous synchronisez ainsi tous les jours, la branche contiendra trois commits de ce genre, et ils arriveront dans main avec la fonctionnalité si vous intégrez sans squash.

Version avec rebase

git switch feature/payment
git fetch origin
git rebase origin/main
# conflits résolus au fil de l'eau, commit par commit : git add, git rebase --continue
git rebase -i origin/main      # facultatif : fusionner les commits brouillons
git push --force-with-lease

La branche semble avoir été créée ce matin à partir du main à jour, sans commits superflus, et le relecteur suit plus facilement les changements étape par étape. Le prix à payer : un push forcé et la nécessité de s'assurer que personne d'autre ne committe sur cette branche.

Ce que main verra au final

Lors de l'intégration via pull request, la différence subsiste. Le style merge produit un graphe avec des ramifications et des merges de synchronisation, le style rebase une chaîne propre de commits de la fonctionnalité, intégrable en avance rapide ou par un seul commit de merge. Le code, lui, sera identique si les conflits sont résolus de la même façon.

Comment trancher en équipe

Répondez à quelques questions. Plusieurs personnes travaillent-elles sur la même branche ? Si oui, rebase est exclu pour cette branche. Quel est le niveau de l'équipe sur Git ? S'il y a souvent des débutants, commencez par merge et squash merge, qui pardonnent les erreurs. Avez-vous besoin d'une chronologie complète pour l'audit et l'analyse d'incidents ? Les commits de merge des fonctionnalités sont alors utiles. Un git log lisible et un usage fréquent de git bisect comptent-ils ? Alors penchez pour rebase et un historique linéaire.

Consignez la décision dans le CONTRIBUTING ou le README du dépôt et activez la protection de la branche principale : interdiction du force push, pull request obligatoire, méthode de fusion autorisée. Une règle imposée par la configuration fonctionne bien mieux que n'importe quel accord oral.

Idées reçues fréquentes

  • « Rebase, c'est pour les experts, merge pour les débutants. » Non : ce sont deux outils pour deux usages différents. Les développeurs expérimentés utilisent les deux.
  • « Les commits de merge, c'est du bruit. » Ceux de synchronisation, souvent oui. Mais le commit de merge qui intègre une fonctionnalité est un repère utile : il permet de voir et d'annuler une tâche entière.
  • « Avec rebase, il y a moins de conflits. » Les conflits sont les mêmes, puisque ce sont les mêmes lignes qui changent. Rebase les répartit simplement commit par commit, là où merge les règle d'un coup.
  • « Rebase fait perdre des commits. » Les anciens commits restent dans git reflog et peuvent être récupérés tant que le ramasse-miettes ne les a pas supprimés.

En résumé

Choisir entre git merge ou rebase, c'est choisir entre une chronologie fidèle et un historique linéaire lisible. Merge est sûr et préserve le contexte, rebase apporte de la clarté mais réécrit les commits. La pratique la plus fiable consiste à combiner les deux : rebaser et nettoyer votre branche tant qu'elle vous appartient, puis intégrer le travail terminé dans les branches partagées par merge ou squash selon les règles de l'équipe. L'essentiel est de s'accorder sur un workflow et de le verrouiller dans les paramètres du dépôt. Les deux stratégies et le travail en équipe avec les branches sont abordés en pratique dans le cours Git.

Questions fréquentes

Faut-il utiliser merge ou rebase pour git pull ?

Pour mettre à jour une branche locale, rebase est plus pratique : vos commits non publiés se placent au-dessus des commits distants récents sans commit de merge superflu. On l'active avec git config --global pull.rebase true.

Peut-on mélanger merge et rebase dans un même projet ?

Oui, et c'est même l'approche la plus répandue : rebase pour vos propres branches, merge pour les branches partagées. Il faut simplement que toute l'équipe connaisse la règle.

Que choisir quand on débute ?

Commencez par merge : il ne réécrit pas l'historique et il est plus difficile de casser quelque chose. Apprenez rebase sur vos branches locales une fois que reflog et force push vous sont familiers.

Le choix de stratégie change-t-il le code final ?

Non, si les conflits sont résolus de la même manière, l'état final des fichiers est identique. Seul l'historique des commits enregistré diffère.

Quelle différence entre squash merge et rebase ?

Le squash merge compresse toute la branche en un seul nouveau commit sur la branche principale, alors que rebase déplace chaque commit séparément. Les deux donnent un historique linéaire, mais le squash perd le détail des étapes.

Apprenez ce sujet en vidéo

Ce sujet est traité en détail avec de la pratique dans le cours « Git de zéro à développeur confirmé ».

Voir le cours