Le rebase
Ce que tu vas apprendre
- Ce que fait
git rebaseet en quoi il diffère degit merge. - Quand le rebase rend service, et comment gérer un conflit pendant un rebase.
- Pourquoi on ne rebase jamais une branche partagée.
Le point de départ
Tu travailles sur une branche profil, qui ajoute une page de profil à ton site. Tu l'as créée depuis main, puis tu as fait deux commits. Pendant ce temps, main a reçu un correctif. Les deux histoires ont divergé.
Tu connais déjà une solution : git merge. Elle crée un commit de fusion qui réunit les deux branches. L'historique garde la trace exacte de ce qui s'est passé, avec ses embranchements.
Le rebase propose une autre solution.
Ce que fait git rebase
git switch profil
git rebase main
Git prend les commits de profil qui ne sont pas sur main, et les rejoue un par un par-dessus le dernier commit de main. Tout se passe comme si tu avais créé ta branche à partir de la version la plus récente.
Point important : les commits rejoués sont de nouveaux commits. Leur contenu est le même, mais leur parent change, donc leur identifiant change aussi. Les anciens commits ne font plus partie d'aucune branche.
Avance pas à pas dans le schéma :
$ git switch profilprofil (C3, C4) est partie de C2, mais main a reçu C5 entre-temps.
Après le rebase, main est un ancêtre direct de profil. Une fusion se fait donc en avance rapide, sans commit de fusion :
git switch main
git merge profil
L'historique devient une ligne droite.
Rebase ou merge ?
git merge | git rebase | |
|---|---|---|
| Historique | garde les embranchements | linéaire |
| Commits existants | inchangés | remplacés par de nouveaux |
| Commit de fusion | oui, si les branches ont divergé | non |
| Sans risque sur une branche partagée | oui | non |
Aucun des deux n'est meilleur dans l'absolu. Le merge dit la vérité sur ce qui s'est passé. Le rebase donne un historique plus facile à lire. Beaucoup d'équipes choisissent une règle commune : suis celle de ton projet.
Quand l'utiliser
Le rebase sert surtout dans deux cas.
Mettre ta branche à jour avant une pull request. Ta branche profil est en retard sur main. Un rebase sur main la remet à jour, et la relecture se fait sur une base récente. À condition que tu sois seul à travailler sur cette branche.
Récupérer le travail des autres sans commit de fusion. Quand tu fais git pull sur ta branche et que tes commits locaux ont divergé du dépôt distant, tu peux rejouer tes commits par-dessus ceux des autres :
git pull --rebase
Pour en faire le comportement par défaut de git pull :
git config --global pull.rebase true
Tes commits locaux n'ont encore été vus par personne : les réécrire ne gêne personne.
Les conflits pendant un rebase
Comme le rebase rejoue les commits un par un, un conflit peut apparaître sur l'un d'eux. Git s'arrête alors sur ce commit. Tu le résous comme pour une fusion : tu édites le fichier, tu retires les marqueurs, puis tu l'indexes. Ensuite, au lieu de git commit :
git add profil.html
git rebase --continue
Git passe au commit suivant. Si tout devient confus, tu peux revenir à l'état d'avant le rebase :
git rebase --abort
git reflog retrouve l'ancien emplacement de ta branche, comme après un git reset.La règle : jamais sur une branche partagée
Le rebase remplace des commits par d'autres. Si ces commits sont déjà sur le dépôt distant et que tes collègues les ont récupérés, ils ont l'ancienne version de l'histoire, toi la nouvelle. Pour publier la tienne, il faudrait forcer le git push. Leur travail pourrait être écrasé, et leurs prochaines fusions deviendraient un casse-tête.
main, ni aucune branche sur laquelle d'autres personnes travaillent. Rebase seulement des commits qui ne sont que chez toi, ou une branche dont tu es le seul utilisateur.C'est la même règle qu'au chapitre précédent : on ne réécrit pas un historique déjà partagé.
À retenir
git rebase mainrejoue les commits de ta branche par-dessus le dernier commit demain.- Les commits rejoués sont de nouveaux commits, avec de nouveaux identifiants.
- Le merge garde l'historique réel, le rebase le rend linéaire.
- En cas de conflit : résoudre,
git add, puisgit rebase --continue, ougit rebase --abortpour tout annuler. - Jamais de rebase sur une branche partagée ou déjà récupérée par d'autres.
Pour aller plus loin
Sources officielles
Ensuite
- Projet
- Lignes de code
- Niveau
- Rez-de-chaussée
- Appartement
- Git
- Pièce
- 6/7
- Plan n°
- git/06.rebase