Git

Merge vs Rebase

Comprenez la différence entre merge et rebase, et apprenez à gérer les conflits

C'est l'une des décisions les plus importantes dans Git. Les deux servent à intégrer des changements d'une branche dans une autre, mais de manière différente.

Imaginez deux chemins qui se rejoignent.

  • Merge : Les deux chemins fusionnent en un point de rencontre
  • Rebase : Un chemin est déplacé pour partir du bout de l'autre

Le Merge : Fusionner avec historique

Le merge fusionne deux branches en créant un commit de merge qui a deux parents.

Situation initiale

main      → A → B → C
                  ↓
feature   →       D → E

Après git merge feature depuis main :

main      → A → B → C ────→ F (merge commit)
                  ↓         ↗
feature   →       D → E ───┘

Un nouveau commit F est créé, qui relie C (main) et E (feature).

Commandes

# 1. Se placer sur la branche de destination
git checkout main

# 2. Récupérer les derniers changements
git pull

# 3. Fusionner la branche feature
git merge feature

Résultat :

Merge made by the 'recursive' strategy.
 src/feature.js | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Avantages

  • Préserve l'historique complet : On voit clairement quand et comment les branches ont été développées
  • Sûr : N'altère jamais les commits existants
  • Simple : Facile à comprendre pour les débutants
  • Traçabilité : Les branches parallèles restent visibles dans l'historique

Inconvénients

  • Historique chargé : Beaucoup de commits de merge si on merge souvent
  • Graphe complexe : L'historique devient un labyrinthe avec beaucoup de branches
  • "Bruit" visuel : Les commits de merge n'apportent pas de code, juste de la fusion

Le Rebase : Réécrire pour un historique linéaire

Le rebase réapplique vos commits un par un sur une autre branche, créant un historique linéaire.

Situation initiale :

main      → A → B → C
                  ↓
feature   →       D → E

Après git rebase main depuis feature :

main      → A → B → C
                      ↓
feature   →           D' → E'

Les commits D et E sont réécrits en D' et E' (nouveaux hash) et réappliqués après C.

Commandes

# 1. Se placer sur la branche à rebaser
git checkout feature

# 2. Rebaser sur main
git rebase main

Résultat :

Successfully rebased and updated refs/heads/feature.

Vos commits de feature sont maintenant après le dernier commit de main.

Avantages

  • Historique linéaire : Facile à lire, comme une ligne droite
  • Pas de commits de merge : Historique propre et clair
  • Facilite le debugging : Plus simple de trouver des bugs avec git bisect
  • Professionnel : Préféré par beaucoup d'équipes et projets open source

Inconvénients

  • Réécrit l'historique : Change les hash des commits ( problématique si déjà partagés)
  • Conflits multiples : Peut nécessiter de résoudre des conflits plusieurs fois
  • Dangereux sur branches partagées : Peut créer des problèmes énormes pour l'équipe
  • Courbe d'apprentissage : Plus complexe à comprendre au début

Précautions

NE JAMAIS REBASER DES COMMITS QUI ONT ÉTÉ PUSHÉS SUR UNE BRANCHE PARTAGÉE

Le rebase réécrit l'historique en créant de nouveaux commits avec de nouveaux hash. Si quelqu'un d'autre a basé son travail sur vos anciens commits, vous allez créer un chaos dans l'équipe.

Quand puis-je rebaser en toute sécurité ?

Vous POUVEZ rebaserNe JAMAIS rebaser
Votre branche de feature personnelle (pas encore pushée)La branche main ou master
Votre branche pushée où vous êtes le seul contributeurLa branche develop ou toute branche partagée
Votre branche locale pour la nettoyer avant une Pull RequestToute branche sur laquelle plusieurs personnes travaillent
Vos commits locaux non partagésDes commits déjà présents sur le serveur distant
En résumé : Vous pouvez rebaser tant que vous êtes le seul à travailler sur la branche et que les commits n'ont pas été partagés avec d'autres développeurs.

Lequel choisir ?

SituationRecommandationPourquoi
Intégrer main dans votre featureRebaseGarde votre feature à jour avec un historique propre
Merger votre feature dans mainMergePréserve l'historique et la traçabilité
Mettre à jour votre branche localeRebaseÉvite les commits de merge inutiles
Branche partagée avec d'autresMergeSûr, ne réécrit pas l'historique
Nettoyer l'historique avant PRRebasePrésente un historique propre aux reviewers
Branches publiques (main, develop)MergeNe jamais réécrire l'historique public

Autres commandes utiles

Cherry-pick

git cherry-pick a1b2c3d

Applique le commit a1b2c3d sur votre branche actuelle.

Cas d'usage : Vous avez committé un bugfix sur la mauvaise branche.

Tags

# Créer un tag annoté (recommandé)
git tag -a v1.0.0 -m "Release version 1.0.0"

# Pousser un tag
git push origin v1.0.0

# Pousser tous les tags
git push --tags

Les tags sont utilisés pour marquer des releases importantes (v1.0.0, v2.0.0, etc.).

Tableau récapitulatif

CommandeDescription
git merge brancheFusionner une branche (crée un commit de merge)
git rebase brancheRebaser sur une branche (historique linéaire)
git rebase -i HEAD~NRebase interactif (nettoyer l'historique)
git merge --abortAnnuler un merge en cours
git rebase --abortAnnuler un rebase en cours
git rebase --continueContinuer après résolution de conflit
git cherry-pick commitAppliquer un commit spécifique
git tag -a v1.0.0 -m "msg"Créer un tag annoté