Rez-de-chausséeG GitPièce 6/7Avancé

Le rebase

Rejouer une branche par-dessus une autre avec git rebase, comparer avec git merge, et savoir quand ne jamais l'utiliser.

Ce que tu vas apprendre

  • Ce que fait git rebase et en quoi il diffère de git 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 :

Rebaser une branche 1 / 4
C1C2C3C4C5mainprofilHEAD
$ git switch profil

profil (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 mergegit rebase
Historiquegarde les embranchementslinéaire
Commits existantsinchangésremplacés par de nouveaux
Commit de fusionoui, si les branches ont divergénon
Sans risque sur une branche partagéeouinon

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
Si un rebase s'est mal terminé, 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.

Ne rebase jamais 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 main rejoue les commits de ta branche par-dessus le dernier commit de main.
  • 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, puis git rebase --continue, ou git rebase --abort pour 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
Lignes de code · fiches rédigées à partir des documentations officielles, sources citées en bas de chaque page.