Aller au contenu

git rebase

Définition

Le rebasage consiste à déplacer ou combiner une série de commits vers un nouveau commit de base. En d’autres termes, il change la base de la branche actuelle d’un commit à un autre, donnant l’impression que la branche a été créée à partir d’un autre commit. Cela se fait en exécutant la commande git rebase. Gardez à l’esprit que même si la branche semble identique, elle est constituée de commits entièrement nouveaux.

git rebase

Utilisation de la commande git rebase

Tout d’abord, nous avons besoin de cette commande pour maintenir un historique de projet linéaire. Par exemple, la branche master progresse après que vous avez commencé à travailler sur une branche de fonctionnalité. Vous avez besoin des mises à jour récentes de la branche master dans votre branche de fonctionnalité, mais l’historique de la branche master doit rester propre. Nous avons besoin d’un historique clair lors de l’exécution d’opérations Git afin de retrouver les régressions. Vous trouverez ci-dessous plus d’informations sur l’utilisation de git rebase :

L’interdiction de rebaser l’historique public

Ne rebasez jamais des commits après les avoir publiés dans l’historique public. Comme dans le cas de l’amendement et de la réinitialisation, cela posera des problèmes de collaboration en équipe. Si vous le faites, l’ancien commit sera remplacé par un nouveau et il semblera qu’une partie de votre projet a disparu.

La différence entre Git rebase standard et Git rebase interactif.

Il existe deux modes pour la commande git rebase : standard et interactif. En mode standard, git rebase appliquera automatiquement les commits de la branche de travail actuelle à la tête de la branche passée en argument. La branche actuelle sera rebasée sur <code><base></code>. Il peut s’agir de différents types de références de commit, comme une balise, un ID, un nom de branche, etc.

git rebase command

bash
git rebase <base>

En mode interactif, git rebase est exécuté avec l’option -i, qui signifie « interactif ». L’avantage du rebasage en mode interactif est de pouvoir modifier les commits individuels pendant le processus, sans avoir à déplacer tous les commits vers la nouvelle base. Grâce à ce mode, vous pouvez nettoyer l’historique en supprimant et en modifiant la séquence existante de commits.

L’exécution de la commande suivante ouvrira un éditeur :

git rebase -i

bash
git rebase --interactive <base>

Dans cet éditeur, saisissez les commandes ci-dessous pour chaque commit qui doit être rebasé. Git commencera à rejouer les commits et à appliquer les commandes de rebase, après avoir déterminé les commandes pour chaque commit.

git rebase example

bash
pick 11a1456 some old commit
pick a23db19 Adds new feature
# Rebase 31d332c..a23db19 onto 31d332c (9 commands)
#
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit

Commandes de rebase interactif

Pendant un rebase interactif, vous pouvez utiliser les commandes suivantes pour chaque commit de la liste todo :

  • drop : supprime le commit du bloc final de commits combinés pendant la relecture.
  • pick : conserve le commit tel quel, sans modifier le message ni le contenu, en le laissant comme commit individuel dans l’historique de la branche.
  • exec : permet d’exécuter un script shell en ligne de commande sur chaque commit marqué pendant la relecture.

Récapitulatif Git

L’un des avantages du rebasage interactif est qu’il permet aux développeurs de ne pas se soucier du désordre de l’historique du projet, car ils peuvent ensuite revenir en arrière et le nettoyer. Ainsi, de nombreux développeurs utilisent cet outil pour rendre l’historique de la branche de fonctionnalité plus propre avant de la fusionner dans la branche master. Nettoyer une branche signifie supprimer les commits sans signification ou obsolètes. En conséquence, les développeurs disposent d’un historique bien planifié et peuvent facilement comprendre quels commits ont été effectués.

Options de configuration

Il existe certaines options de rebase définies à l’aide de la commande git config. Ces options modifient le comportement et la sortie de git rebase.

  • rebase.stat: par défaut une valeur booléenne false, qui active ou désactive l’affichage d’un diffstat visuel montrant les changements depuis le dernier rebase.
  • rebase.autoSquash: une valeur booléenne qui active ou désactive le comportement --autosquash.
  • rebase.missingCommitsCheck: peut être définie sur plusieurs valeurs modifiant le comportement du rebase en ce qui concerne les commits manquants. | warn | Un message d’avertissement est affiché en mode interactif et signale les commits supprimés. | |---|---| | error | Le rebase est arrêté et des messages d’avertissement concernant les commits supprimés sont affichés. | | ignore | L’option par défaut, qui ignore tous les avertissements relatifs aux commits manquants. |
  • rebase.instructionFormat: une chaîne au format git log utilisée pour formater l’affichage du rebase interactif.

Application avancée du rebase

La commande git rebase peut recevoir l’argument de ligne de commande --onto, auquel cas la commande se développe comme suit :

git rebase --onto

bash
git rebase --onto <newbase> <oldbase> <branch>

La commande --onto permet une application avancée du rebase, car elle autorise le passage de refs spécifiques comme commits de base du rebase.

Voyons son comportement sur un exemple :

git rebase --onto example

bash
o---o---o---o---o master
 \
 o---o---o---o---o featureX
 \
 o---o---o featureY

Bien que featureY ait été initialement basée sur featureX, elle est indépendante des changements de featureX et peut être rebasée directement sur master. Cette commande rejoue les commits de featureY sur master, détachant ainsi featureY de featureX.

git rebase --onto command

bash
git rebase --onto master featureX featureY

FeatureX est le <code><oldbase></code>, master est le <code><newbase></code>, et featureY est la branche en cours de rebasage. Voici le résultat :

git rebase usage

bash
o---o---o featureY
 /
 o---o---o---o---o master
 \
 o---o---o---o---o featureX

Les dangers du rebasage

Le premier danger de l’utilisation de la commande git rebase est qu’elle peut provoquer davantage de conflits de fusion pendant un processus de rebasage, en particulier dans les cas où vous avez une branche de longue durée qui a divergé de master. Tôt ou tard, vous pouvez décider de rebaser sur master, qui peut contenir de nouveaux commits avec lesquels les changements de votre branche peuvent entrer en conflit. La solution à la situation décrite ci-dessus consiste à rebaser plus souvent la branche sur master et à effectuer des commits plus fréquents. Afin de poursuivre ou d’annuler le rebase tout en résolvant les conflits, vous pouvez utiliser les arguments --continue et --abort avec git rebase. Un autre risque plus grave est que certains commits puissent être perdus lors de la réécriture interactive de l’historique. Exécuter rebase en mode interactif avec certaines sous-commandes comme squash ou drop supprime des commits du journal immédiat de la branche. Il peut sembler que les commits soient supprimés définitivement. La solution est le git reflog, qui permet de restaurer ces commits et d’annuler l’ensemble du rebase.

Récupération après un rebase en amont

Si un autre utilisateur a rebasé puis forcé l’envoi sur la branche sur laquelle vous effectuez vos commits, un git pull écrasera alors tout commit basé sur cette branche précédente avec la pointe envoyée de force. Git rebase vous permet d’utiliser le reflog de la branche distante. Vous pouvez y trouver une ref avant qu’elle ne soit rebasée. Vous pouvez ensuite rebaser votre branche sur cette ref distante avec l’option --onto.

Practice

Quelles sont les affirmations correctes à propos de la commande `git rebase` telle que décrite dans le tutoriel Git de W3Docs ?

Trouvez-vous cela utile?

Aperçu dual-run — comparez avec les routes Symfony en production.