Le débat rebase vs merge est l'une des discussions les plus courantes dans les workflows Git. Les deux commandes intègrent les changements d'une branche dans une autre, mais de manières fondamentalement différentes.
Comment fonctionne Git Merge
Git merge crée un nouveau "commit de merge" qui lie les historiques des deux branches.
Git trouve l'ancêtre commun des deux branches, puis crée un nouveau commit combinant les changements.
A---B---C feature
/ \
D---E---F---G---H main (merge commit)
$ git checkout main
$ git merge featureComment fonctionne Git Rebase
Git rebase déplace (ou "rejoue") vos commits au-dessus d'une autre branche, créant une séquence linéaire.
Git retire temporairement vos commits, met à jour la branche, puis réapplique chaque commit un par un.
Before rebase:
A---B---C feature
/
D---E---F---G main
After rebase:
A'--B'--C' feature
/
D---E---F---G main
$ git checkout feature
$ git rebase mainComparaison visuelle
╔═══════════════════════════════════════════╗
║ MERGE RESULT ║
║ ║
║ D---E---F---G---H main ║
║ \ / ║
║ A---B---C feature ║
║ ║
║ ✓ Preserves all commits ║
║ ✓ Shows merge point ║
║ ✗ Non-linear history ║
╚═══════════════════════════════════════════╝
╔═══════════════════════════════════════════╗
║ REBASE RESULT ║
║ ║
║ D---E---F---G---A'--B'--C' main ║
║ ║
║ ✓ Clean linear history ║
║ ✓ Easy to read ║
║ ✗ Rewrites commit hashes ║
╚═══════════════════════════════════════════╝Quand utiliser Merge
- Branches publiques/partagées — Merge ne réécrit jamais l'historique.
- Préserver le contexte — Le commit de merge montre quand une branche a été intégrée.
- Collaboration d'équipe — Quand plusieurs personnes travaillent sur la même branche.
- Branches de release — Préserve le point d'intégration exact.
# Merge with merge commit (recommended for main)
$ git checkout main
$ git merge --no-ff feature
$ git push origin mainQuand utiliser Rebase
- Branches feature (avant merge dans main) — Crée un historique linéaire propre.
- Rester à jour — Rebase votre branche feature sur main sans commits de merge.
- Avant soumission de PR — Des commits propres sont plus faciles à reviewer.
- Nettoyer les commits locaux — Rebase interactif pour squash, réordonner, éditer.
# Update feature branch with latest main
$ git checkout feature
$ git rebase main
# If conflicts occur, resolve them, then:
$ git add .
$ git rebase --continueRebase interactif : squash, fixup, réordonner
Le rebase interactif (git rebase -i) est l'une des fonctionnalités les plus puissantes de Git.
$ git rebase -i HEAD~4
# Editor opens:
pick a1b2c3d Add user authentication
pick e4f5g6h Fix typo in auth
pick i7j8k9l Add password validation
pick m0n1o2p Fix lint error
# Change to:
pick a1b2c3d Add user authentication
fixup e4f5g6h Fix typo in auth # merge into previous, discard message
pick i7j8k9l Add password validation
fixup m0n1o2p Fix lint error # merge into previous, discard message
# Result: 2 clean commits instead of 4
# Commands:
# pick = use commit as-is
# squash = merge into previous commit, keep message
# fixup = merge into previous commit, discard message
# reword = use commit but edit message
# drop = remove commit entirelyRègle d'or : Ne jamais Rebase les branches publiques
Si une branche a été poussée et d'autres y travaillent, NE PAS la rebase.
Règle d'or : Ne rebase que les commits non poussés sur un remote partagé.
# ❌ DANGEROUS: Rebasing a shared branch
$ git checkout main
$ git rebase feature # NEVER do this!
# ✅ SAFE: Rebasing your own feature branch
$ git checkout my-feature # only I work on this
$ git rebase main # safe!
$ git push --force-with-lease origin my-featureMerge vs Rebase : Comparaison complète
| Critère | Merge | Rebase |
|---|---|---|
| History | Non-linear, preserves branches | Linear, clean |
| Commit hashes | Preserved | Changed (new hashes) |
| Conflict resolution | Once (in merge commit) | Per commit (may resolve multiple times) |
| Traceability | High (merge commit shows context) | Medium (linear but no branch info) |
| Safety | Safe (no history rewrite) | Risky (rewrites history) |
| For shared branches | ✅ | ❌ |
| For personal branches | ✅ | ✅ |
| Reversibility | Easy (git revert) | Harder (requires reflog) |
| git bisect | Harder (non-linear) | Easier (linear history) |
Workflows Git courants
Feature Branch Workflow
Créer branche → développer → rebase sur main → merge avec --no-ff.
$ git checkout -b feature/login
# ... develop ...
$ git rebase main # clean up history
$ git checkout main
$ git merge --no-ff feature/login # merge with commit
$ git branch -d feature/loginGitflow Workflow
Utilise develop, feature, release, hotfix. Toujours merge entre branches longue durée.
# Always merge between long-lived branches
$ git checkout develop
$ git merge --no-ff feature/login
$ git checkout release/1.0
$ git merge --no-ff develop
$ git checkout main
$ git merge --no-ff release/1.0
$ git tag v1.0Trunk-Based Development
Branches feature courtes (< 1 jour). Rebase fréquent, merge rapide.
# Short-lived branch, rebase often
$ git checkout -b fix/typo
# ... quick fix ...
$ git rebase main
$ git checkout main
$ git merge fix/typo # fast-forward
$ git pushScénarios dangereux
| Scénario | Risque | Prévention |
|---|---|---|
| Rebase main/master | Everyone's history breaks | Never rebase main |
| Rebase shared feature branch | Collaborators face divergent history | Use merge for shared branches |
| git push --force | Overwrites remote changes | Use --force-with-lease instead |
| Wrong conflict resolution during rebase | Code loss or corruption | Review each conflict, use git rebase --abort to restart |
| Rebase branch with merge commits | Merge commits flattened, confusing | Use --rebase-merges or avoid |
Questions fréquemment posées
Peut-on annuler un rebase ?
Oui. Utilisez git reflog pour trouver le hash avant le rebase, puis git reset --hard.
Rebase ou merge pour mettre à jour ma branche feature ?
Seul sur la branche : rebase. Branche partagée : merge.
Qu'est-ce que git pull --rebase ?
Rejoue vos commits locaux au-dessus des changements distants, sans commit de merge.
Que se passe-t-il si je rebase une branche déjà poussée ?
Vous devrez faire un force push. Les autres auront un historique divergent.
Squash merge = rebase + squash ?
Résultat similaire, mécanisme différent. Le rebase -i offre plus de contrôle.
Lequel pour les contributions open source ?
La plupart des projets open source préfèrent des commits rebasés et propres.