la commandegit rebase
a la réputation d’être magique git voodoo que les débutants devraient éviter, mais elle peut en fait rendre la vie beaucoup plus facile pour une équipe de développement lorsqu’elle est utilisée avec soin. Dans cet article, nous allons comparer git rebase
avec la commande associée git merge
et identifier toutes les opportunités potentielles d’intégrer le rebasage dans le flux de travail Git typique.,
Présentation Conceptuelle
La première chose à comprendre au sujet de git rebase
est qu’il résout le même problème git merge
. Ces deux commandes sont conçues pour intégrer les modifications d’une branche à une autre branche—elles le font simplement de manières très différentes.
considérez ce qui se passe lorsque vous commencez à travailler sur une nouvelle fonctionnalité dans une branche dédiée, puis un autre membre de l’équipe met à jour la branchemaster
avec de nouveaux commits. Il en résulte un historique fourchu, qui devrait être familier à tous ceux qui ont utilisé Git comme outil de collaboration.,
Maintenant, imaginons que la nouvelle s’engage dans master
sont pertinentes à la fonction pour laquelle vous travaillez. Pour incorporer les nouveaux commits dans votre branchefeature
, vous avez deux options: fusionner ou rebaser.,
L’Option de fusion
l’option la plus simple consiste à fusionner la branche master
dans la branche feature en utilisant quelque chose comme ceci:
git checkout feature git merge master
ou, vous pouvez condenser cela en une seule ligne:
git merge feature master
cela crée un nouveau « commit de fusion” dans la branche feature
qui relie les historiques des deux branches, vous donnant une structure de branche qui ressemble à ceci:
la fusion est agréable car c’est une opération non destructive. Les branches existantes ne sont en aucun cas modifiées., Cela évite tous les pièges potentiels du rebasage (discutés ci-dessous).
d’autre part, cela signifie également que la branchefeature
aura une validation de fusion étrangère chaque fois que vous aurez besoin d’incorporer des modifications en amont. Si master
est très actif, cela peut polluer un peu l’historique de votre branche de fonctionnalités. Bien qu’il soit possible d’atténuer ce problème avec les options avancées git log
, il peut être difficile pour les autres développeurs de comprendre l’historique du projet.,
Le Rebase Option
Comme une alternative à la fusion, vous pouvez rebase la balise feature
branche sur master
branche en utilisant les commandes suivantes:
git checkout feature git rebase master
Cela déplace l’ensemble de la feature
branche pour commencer sur le bout de la balise master
succursale, de manière efficace en intégrant toutes les nouvelles s’engage dans master
. Mais, au lieu d’utiliser un commit de fusion, rebasing réécrit l’historique du projet en créant de nouveaux commits pour chaque commit dans la branche d’origine.,
le principal avantage du rebasage est que vous obtenez un historique de projet beaucoup plus propre. Tout d’abord, il élimine les commits de fusion inutiles requis par git merge
. Deuxièmement, comme vous pouvez le voir dans le diagramme ci—dessus, le rebasage entraîne également un historique de projet parfaitement linéaire-vous pouvez suivre la pointe de feature
jusqu’au début du projet sans aucune fourche. Cela rend plus facile de naviguer dans votre projet avec des commandes comme git log
, git bisect
et gitk
.,
Mais, il y a deux compromis pour cette histoire de commit vierge: la sécurité et la traçabilité. Si vous ne suivez pas la règle d’or du rebasage, la réécriture de l’historique du projet peut être potentiellement catastrophique pour votre flux de travail de collaboration. Et, chose moins importante, le rebasage perd le contexte fourni par un commit de fusion—vous ne pouvez pas voir quand les modifications en amont ont été intégrées à la fonctionnalité.
Interactif Complet
Interactif complet vous donne la possibilité de modifier l’engage comme ils sont déplacés vers la nouvelle branche., C’est encore plus puissant qu’un rebase automatisé, car il offre un contrôle complet sur l’historique des commits de la branche. Typiquement, ceci est utilisé pour nettoyer un historique désordonné avant de fusionner une branche de fonctionnalité dans master
.,
pour commencer une session de rebasage interactive, passez l’option i
à la commande git rebase
:
git checkout feature git rebase -i master
cela ouvrira un éditeur de texte listant tous les commits sur le point d’être déplacés:
pick 33d5b7a Message for commit #1 pick 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3
cette liste définit exactement à quoi ressemblera la branche après le rebase. En modifiant la commandepick
et/ou en réorganisant les entrées, vous pouvez faire ressembler l’historique de la branche à ce que vous voulez., Par exemple, si le 2ème commit corrige un petit problème dans le 1er commit, vous pouvez les condenser en un seul commit avec la commande fixup
:
pick 33d5b7a Message for commit #1 fixup 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3
lorsque vous Enregistrez et fermez le fichier, Git effectue le rebase selon vos instructions, ce qui donne un historique de projet qui ressemble à d8e38838f6″>
l’élimination de commits insignifiants comme celui-ci rend l’historique de votre fonctionnalité beaucoup plus facile à comprendre. C’est quelque chose que git merge
ne peut tout simplement pas faire.,
la règle d’or du rebasage
Une fois que vous comprenez ce qu’est le rebasage, la chose la plus importante à apprendre est de ne pas le faire. La règle d’or de git rebase
est de ne jamais l’utiliser sur les branches publiques.
Par exemple, de penser à ce qui pourrait arriver si vous relocalisée master
dans votre feature
branche:
Le rebase se déplace tous les commits dans master
sur la pointe du feature
. Le problème est que cela ne s’est passé dans votre référentiel., Tous les autres développeurs travaillent toujours avec l’original master
. Étant donné que le rebasage entraîne de nouveaux commits, Git pensera que l’historique de votre branche master
a divergé de celui de tous les autres.
la seule façon de synchroniser les deux branches master
est de les fusionner ensemble, ce qui entraîne un commit de fusion supplémentaire et deux ensembles de commits contenant les mêmes modifications (celles d’origine et celles de votre branche rebasée). Inutile de dire que c’est une situation très confuse.,
donc, avant d’exécutergit rebase
, demandez-vous toujours: « est-ce que quelqu’un d’autre regarde cette branche? »Si la réponse est oui, retirez vos mains du clavier et commencez à penser à un moyen non destructif d’apporter vos modifications (par exemple, la commande git revert
). Sinon, vous pouvez réécrire l’histoire autant que vous le souhaitez.
forcer
Si vous essayez de renvoyer la branchemaster
rebasée vers un dépôt distant, Git vous en empêchera car elle est en conflit avec la branchemaster
distante., Mais, vous pouvez forcer le push à passer en passant l’indicateur--force
, comme ceci:
# Be very careful with this command! git push --force
cela écrase la branche distantemaster
pour correspondre à celle rebasée de votre référentiel et rend les choses très déroutantes pour le reste de Alors, soyez très prudent d’utiliser cette commande uniquement lorsque vous savez exactement ce que vous faites.
l’une des seules fois où vous devez forcer est lorsque vous avez effectué un nettoyage local après avoir poussé une branche de fonctionnalité privée vers un référentiel distant (par exemple, à des fins de sauvegarde)., C’est comme dire: « Oups, je ne voulais pas vraiment pousser cette version originale de la branche de fonctionnalités. Prenez le courant à la place. »Encore une fois, il est important que personne ne travaille sur les commits de la version originale de la branche de fonctionnalité.
procédure pas à pas du Workflow
le rebasage peut être intégré à votre workflow git existant autant ou aussi peu que votre équipe est à l’aise avec. Dans cette section, nous examinerons les avantages que le rebasage peut offrir aux différentes étapes du développement d’une fonctionnalité.,
la première étape de tout workflow qui exploite git rebase
consiste à créer une branche dédiée pour chaque fonctionnalité. Cela vous donne la structure de branche nécessaire pour utiliser le rebasage en toute sécurité:
Nettoyage Local
l’une des meilleures façons d’intégrer le rebasage dans votre flux de travail est de nettoyer les fonctionnalités locales en cours. En effectuant périodiquement un rebase interactif, vous pouvez vous assurer que chaque validation de votre fonctionnalité est ciblée et significative., Cela vous permet d’écrire votre code sans vous soucier de le diviser en commits isolés—vous pouvez le réparer après coup.
lorsque vous appelezgit rebase
, vous avez deux options pour la nouvelle base: la branche parent de la fonctionnalité (par exemple,master
), ou un commit antérieur dans votre fonctionnalité. Nous avons vu un exemple de la première option dans la section rebasage interactif. La dernière option est agréable quand vous avez seulement besoin de corriger les derniers commits. Par exemple, la commande suivante commence un rebase interactif de seulement les 3 derniers commits.,
git checkout feature git rebase -i HEAD~3
en spécifiantHEAD~3
comme nouvelle base, vous ne déplacez pas réellement la branche—vous réécrivez simplement interactivement les 3 commits qui la suivent. Notez que cela n’intégrera pas les modifications en amont dans la branchefeature
.
Si vous souhaitez réécrire l’intégralité de la fonctionnalité en utilisant cette méthode, la commandegit merge-base
peut être utile pour trouver la base d’origine de la branchefeature
., Ce qui suit renvoie l’ID de validation de la base d’origine, que vous pouvez ensuite passer à git rebase
:
git merge-base feature master
Cette Utilisation du rebasage interactif est un excellent moyen d’introduire git rebase
dans votre flux de travail, car La seule chose que les autres développeurs verront est votre produit fini, qui devrait être un historique de branche propre et facile à suivre.
Mais encore une fois, cela ne fonctionne que pour la branche privées., Si vous collaborez avec d’autres développeurs via la même branche de fonctionnalités, cette branche est publique et vous n’êtes pas autorisé à réécrire son historique.
il n’y a pas d’alternativegit merge
pour nettoyer les commits locaux avec un rebase interactif.
intégration des modifications en amont dans une fonctionnalité
dans la section Aperçu conceptuel, nous avons vu comment une branche de fonctionnalité peut intégrer des modifications en amont à partir demaster
en utilisant soitgit merge
ougit rebase
., La fusion est une option sûre qui préserve l’historique complet de votre référentiel, tandis que le rebasage crée un historique linéaire en déplaçant votre branche de fonctionnalité sur la pointe de master
.
cette utilisation degit rebase
est similaire à un nettoyage local (et peut être effectuée simultanément), mais dans le processus, elle intègre les commits amont demaster
.
Gardez à l’esprit qu’il est parfaitement légal de rebase sur une branche distante au lieu de master
., Cela peut se produire lorsque vous collaborez sur la même fonctionnalité avec un autre développeur et que vous devez intégrer leurs modifications dans votre référentiel.,
par exemple, si vous et un autre développeur nommé John avez ajouté des commits à la branche feature
, votre référentiel pourrait ressembler à ce qui suit après avoir récupéré la branche distante feature
à partir du référentiel de John:
Vous pouvez résoudre ce modifications de master
: soit fusionner votre feature
avec john/feature
, soit rebaser votre feature
local sur la pointe de john/feature
.,
notez que ce rebase ne viole pas la règle d’or du rebasage car seuls vos commits locauxfeature
sont déplacés—tout ce qui précède est intact. C’est comme dire: « ajoutez mes changements à ce que John a déjà fait.” Dans la plupart des cas, c’est plus intuitif que de synchroniser avec la branche distante via un commit de fusion.
par défaut, la commande git pull
effectue une fusion, mais vous pouvez la forcer à intégrer la branche distante avec un rebase en lui passant l’option --rebase
.,
révision D’une fonctionnalité avec une Pull Request
Si vous utilisez des pull requests dans le cadre de votre processus de révision de code, vous devez éviter d’utilisergit rebase
après avoir créé la pull request. Dès que vous effectuez la pull request, d’autres développeurs examineront vos commits, ce qui signifie qu’il s’agit d’une branche publique. En réécrivant son historique, il sera impossible pour Git et vos coéquipiers de suivre les commits de suivi ajoutés à la fonctionnalité.
toute modification d’autres développeurs doit être incorporée avecgit merge
au lieu degit rebase
.,
Pour cette raison, il est généralement une bonne idée de nettoyer votre code avec un rebase interactif avant de soumettre votre demande d’extraction.
intégration d’une fonctionnalité approuvée
Une fois qu’une fonctionnalité a été approuvée par votre équipe, vous avez la possibilité de rebaser la fonctionnalité sur la pointe de la branchemaster
avant d’utilisergit merge
pour intégrer la fonctionnalité,
c’est une situation similaire à l’intégration de modifications en amont dans une branche de fonctionnalité, mais comme vous n’êtes pas autorisé à réécrire les commits dans la branchemaster
, vous devez éventuellement utilisergit merge
pour intégrer la fonctionnalité. Cependant, en effectuant un rebase avant la fusion, vous êtes assuré que la fusion sera expédiée rapidement, ce qui donne un historique parfaitement linéaire. Cela vous donne également la possibilité d’écraser tous les commits de suivi ajoutés lors d’une pull request.,
Si vous n’êtes pas totalement à l’aise avec git rebase
, vous pouvez toujours effectuer le rebase temporaire de la branche. De cette façon, si vous gâchez accidentellement l’historique de votre fonctionnalité, vous pouvez vérifier la branche d’origine et réessayer. Par exemple:
git checkout feature git checkout -b temporary-branch git rebase -i master # git checkout master git merge temporary-branch
résumé
et c’est tout ce que vous devez vraiment savoir pour commencer à rebaser vos branches., Si vous préférez un historique propre et linéaire exempt de commits de fusion inutiles, vous devez atteindre git rebase
au lieu de git merge
lors de l’intégration des modifications d’une autre branche.
en revanche, si vous souhaitez conserver l’historique complet de votre projet et éviter le risque de ré-écriture publique s’engage, vous pouvez coller avec des git merge
. L’une ou l’autre option est parfaitement valide, mais au moins maintenant vous avez la possibilité de tirer parti des avantages de git rebase
.
Laisser un commentaire