git rebase rejoue vos commits sur une nouvelle base pour obtenir un
historique linéaire. Au lieu de créer un commit de fusion comme
git merge, le rebase réécrit l’historique comme si vous aviez
commencé votre travail depuis le dernier commit de la branche cible.
Ce guide couvre le rebase interactif, la règle d’or à ne jamais
enfreíndre et le rebase --onto pour les déplacements avancés.
Prérequis : Merge et résolution de conflits.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre le mécanisme du rebase et pourquoi les hashes changent
- Comparer merge et rebase pour choisir la bonne stratégie
- Appliquer la règle d’or : ne jamais rebaser une branche partagée
- Utiliser
rebase -ipour nettoyer un historique avant de pousser - Transporter une branche avec
rebase --onto
Le principe du rebase
Section intitulée « Le principe du rebase »Imaginons deux branches divergentes :
Avant rebase : C4 ← C5 (main) /C1 ← C2 ← C3 \ C6 ← C7 (feature ← HEAD)Un git merge main depuis feature créerait un commit de fusion.
Un git rebase main fait autre chose :
- Git identifie les commits propres à
feature(C6,C7) - Git les « détache » temporairement
- Git avance
featuresur le bout demain(C5) - Git rejoue
C6etC7un par un, créant de nouveaux commits (C6',C7')
Après git rebase main (depuis feature) : C6' ← C7' (feature ← HEAD) /C1 ← C2 ← C3 ← C4 ← C5 (main)L’historique est maintenant linéaire. Les commits C6' et C7'
sont de nouveaux commits (hash différent) mais avec le même contenu
que C6 et C7.
Rebase en pratique
Section intitulée « Rebase en pratique »# 1. Basculez sur votre branche featuregit switch feature
# 2. Rebasez sur maingit rebase main
# 3. Retournez sur main et faites un fast-forwardgit switch maingit merge feature # Fast-forward garantiAprès le rebase, le merge depuis main est toujours un fast-forward
puisque feature est « devant » main dans le graphe linéaire.
Résoudre les conflits pendant un rebase
Section intitulée « Résoudre les conflits pendant un rebase »Le rebase rejoue les commits un par un. Un conflit peut survenir à chaque étape :
# Git s'arrête et affiche :# CONFLICT (content): Merge conflict in fichier.txt# ...# hint: Resolve all conflicts manually, mark them as resolved with# hint: "git add/rm <conflicted_files>", then run "git rebase --continue".-
Éditez le fichier et résolvez le conflit (mêmes marqueurs que dans un merge)
-
Marquez le fichier résolu :
Fenêtre de terminal git add fichier.txt -
Continuez le rebase :
Fenêtre de terminal git rebase --continue -
Si le conflit suivant apparaît, répétez les étapes 1 à 3.
Vous pouvez aussi abandonner le rebase en cours :
git rebase --abortLe dépôt revient exactement à l’état d’avant le rebase.
La règle d’or du rebase
Section intitulée « La règle d’or du rebase »Ce qui se passe concrètement si vous rebasez de l’historique pushé
Section intitulée « Ce qui se passe concrètement si vous rebasez de l’historique pushé »Imaginez que vous poussez C6 et C7 sur origin/feature. Un
collègue les récupère (git fetch). Vous rebasez ensuite et
force-pushup C6' et C7' (mêmes contenus, nouveaux hashes).
Votre collègue se retrouve avec :
Son historique local : ... ← C6 ← C7 (sa branche, basée sur les anciens commits)
Ce qu'affiche origin/feature après votre force-push : ... ← C6' ← C7' (nouveaux hashes)Git voit deux histoires divergentes. La réconciliation est complexe et génère des commits dupliqués dans l’historique final.
La règle est simple :
| Situation | Action |
|---|---|
| Branche locale, jamais poussée | Rebase sans souci |
| Branche poussée, mais vous êtes le seul à travailler dessus | Rebase possible (puis git push --force-with-lease) |
| Branche partagée avec d’autres | Merge uniquement |
git pull --rebase
Section intitulée « git pull --rebase »Par défaut, git pull fait un fetch + merge. Avec --rebase, il fait
un fetch + rebase : vos commits locaux sont rejoués sur les commits
distants.
git pull --rebase origin mainPour en faire le comportement par défaut :
git config --global pull.rebase trueC’est la configuration recommandée pour garder un historique propre quand vous travaillez seul sur une branche.
git rebase --onto : changer la base
Section intitulée « git rebase --onto : changer la base »--onto permet de déplacer une chaîne de commits d’une base vers
une autre. C’est utile quand vous avez branché depuis la mauvaise
branche :
Avant : C8 ← C9 (ma-feature ← HEAD) / C6 ← C7 (develop) /C1 ← C2 ← C3 ← C4 ← C5 (main)Vous voulez que ma-feature parte de main au lieu de develop :
git rebase --onto main develop ma-featureAprès : C8' ← C9' (ma-feature ← HEAD) /C1 ← C2 ← C3 ← C4 ← C5 (main) \ C6 ← C7 (develop)La syntaxe : git rebase --onto <nouvelle-base> <ancienne-base> <branche>.
Merge vs rebase : quand utiliser quoi ?
Section intitulée « Merge vs rebase : quand utiliser quoi ? »| Critère | Merge | Rebase |
|---|---|---|
| Historique | Non-linéaire (losanges) | Linéaire |
| Traçabilité | Commit de merge explicite | Pas de commit de merge |
| Sécurité | Pas de réécriture | Réécrit les hash |
| Conflits | Une seule résolution | Résolution commit par commit |
| Travail partagé | Toujours sûr | Dangereux si poussé |
Recommandation pragmatique :
- Rebase pour mettre à jour votre branche locale avec les derniers
changements de
main - Merge (avec
--no-ff) pour intégrer une branche terminée dansmain
Cette approche donne un historique propre avec des points de merge explicites marquant chaque fonctionnalité.
Dépannage : problèmes courants
Section intitulée « Dépannage : problèmes courants »| Symptôme | Cause probable | Solution |
|---|---|---|
| Conflit sur chaque commit pendant le rebase | Divergence importante entre branches | Envisagez un merge plutôt qu’un rebase |
fatal: It seems that there is already a rebase-merge directory | Rebase précédent non terminé | git rebase --abort pour nettoyer |
| Commits dupliqués après push | Rebase de commits déjà poussés | git reflog pour retrouver l’état, évitez à l’avenir |
! [rejected] (non-fast-forward) après rebase | Le remote a les anciens commits | git push --force-with-lease (si branche perso) |
À retenir
Section intitulée « À retenir »- Rebase rejoue vos commits sur une nouvelle base → historique linéaire
- Merge crée un commit de fusion → préserve l’historique tel quel
- Règle d’or : ne jamais rebaser des commits déjà partagés
git pull --rebasegarde un historique propre au quotidiengit rebase --ontodéplace une chaîne de commits vers une autre base- En cas de doute, privilégiez le merge : il est toujours sûr