Dans le flux de travail Git fondamental, vous développez une nouvelle fonctionnalité dans une branche de sujet dédiée, puis vous la fusionnez dans une branche de production une fois celle-ci terminée. Cela fait fusionner
un outil intégral pour combiner des branches. Cependant, ce n'est pas le seul que propose Git.
Comme alternative au scénario ci-dessus, vous pouvez combiner les branches avec le git rebase
commander. Au lieu de lier les branches avec un commit de fusion, le rebasement déplace toute la branche de fonctionnalité vers la pointe de maîtriser
comme indiqué ci-dessous.
Cela sert le même objectif que fusionner
, intégrer des commits de différentes branches. Mais il y a deux raisons pour lesquelles nous pourrions vouloir opter pour un rebase plutôt que pour une fusion:
Dans ce tutoriel, nous allons explorer ces deux cas d’utilisation courants de git rebase
. Malheureusement, les avantages de git rebase
venir à un compromis. Utilisé de manière incorrecte, il peut s’agir de l’une des opérations les plus dangereuses que vous puissiez effectuer dans un référentiel Git. Donc, nous allons également examiner de près les dangers de rebasement.
Ce tutoriel suppose que vous maîtrisiez les commandes Git de base et les workflows de collaboration. Vous devez être à l'aise pour préparer et créer des instantanés, développer des fonctionnalités dans des branches isolées, fusionner des branches et pousser / extraire des branches vers / depuis des référentiels distants..
Le premier cas d'utilisation que nous allons explorer implique une histoire de projet divergente. Considérez un référentiel dans lequel votre branche de production a évolué pendant que vous développiez une fonctionnalité:
Pour rebaser le fonctionnalité
branche sur le maîtriser
branche, vous exécuterez les commandes suivantes:
fonctionnalité git checkout maître git rebase
Cette greffe le fonctionnalité
branche de son emplacement actuel à la pointe de la maîtriser
branche:
Il existe deux scénarios dans lesquels vous souhaiteriez procéder. Premièrement, si la fonctionnalité s’appuie sur les nouveaux commits de maîtriser
, il y aurait maintenant accès. Deuxièmement, si la fonctionnalité était complète, elle serait désormais configurée pour une fusion rapide vers l’avenir. maîtriser
. Dans les deux cas, le changement de base donne une histoire linéaire, alors que fusionner
entraînerait des fusions de fusion inutiles.
Par exemple, considérons ce qui se passerait si vous intégriez les commits en amont avec une fusion au lieu d'une base:
Fonctionnalité Git Checkout Maître de fusion Git
Cela nous aurait donné un engagement de fusion supplémentaire dans le fonctionnalité
branche. De plus, cela se produirait chaque fois que vous voudriez incorporer des commits en amont dans votre fonctionnalité. Finalement, l'historique de votre projet serait encombré de commits de fusion sans signification.
Ce même avantage peut être vu lors de la fusion dans l'autre sens. Sans rebase, intégrant le fini fonctionnalité
branche en maîtriser
nécessite un commit de fusion. Bien qu'il s'agisse en réalité d'un commit de fusion significatif (en ce sens qu'il représente une fonctionnalité terminée), l'historique résultant est rempli de forks:
Lorsque vous rebasez avant de fusionner, Git peut effectuer une avance rapide. maîtriser
à la pointe de fonctionnalité
. Vous trouverez une histoire linéaire de la progression de votre projet dans le journal git
sortie-les commets dans fonctionnalité
sont soigneusement regroupés au-dessus des commits en maîtriser
. Ce n’est pas nécessairement le cas lorsque les branches sont liées par un commit de fusion..
Quand tu cours git rebase
, Git prend chaque commit de la branche et les déplace un par un sur la nouvelle base. Si l'un de ces commits modifie la ou les mêmes lignes de code que le commuté en amont, il en résultera un conflit..
le fusionner
Cette commande vous permet de résoudre tous les conflits de la branche à la fin de la fusion, ce qui est l’un des principaux objectifs d’un commit de fusion. Cependant, cela fonctionne un peu différemment lorsque vous changez de base. Les conflits sont résolus sur une base par engagement. Donc si git rebase
trouve un conflit, il arrêtera la procédure de rebasement et affichera un message d'avertissement:
Fusion automatique du fichier readme.txt CONFLICT (contenu): conflit de fusion dans le fichier readme.txt Échec de la fusion des modifications… Une fois ce problème résolu, exécutez "git rebase --continue". Si vous préférez ignorer ce correctif, exécutez à la place "git rebase --skip". Pour extraire la branche d'origine et arrêter le rebasement, lancez "git rebase --abort".
Visuellement, voici à quoi ressemble votre historique de projet git rebase
rencontre un conflit:
Les conflits peuvent être inspectés en exécutant statut git
. La sortie ressemble beaucoup à un conflit de fusion:
Chemins sans fusion: (utilisez "git reset HEAD… "Pour décompresser) (utilisez" git add … "Pour marquer la résolution) à la fois modifiés: readme.txt aucune modification ajoutée à commettre (utilisez" git add "et / ou" git commit -a ")
Pour résoudre le conflit, ouvrez le fichier en conflit (lisez-moi.txt dans l'exemple ci-dessus), recherchez les lignes affectées et modifiez-les manuellement pour obtenir le résultat souhaité. Indiquez ensuite à Git que le conflit est résolu en organisant le fichier:
git add readme.txt
Notez que c’est exactement la même façon de marquer un fusionner
conflit comme résolu. Mais souvenez-vous que vous êtes en train de rebaser. Vous ne voulez pas oublier le reste des commits qui doivent être déplacés. La dernière étape consiste à dire à Git de finir de rebasonner avec le --continuer
option:
git rebase --continue
Cela déplacera le reste des commits, un par un, et si d'autres conflits surviennent, vous devrez répéter ce processus encore une fois..
Si vous ne voulez pas résoudre le conflit, vous pouvez opter pour la --sauter
ou --avorter
drapeaux. Ce dernier est particulièrement utile si vous n’avez aucune idée de ce qui se passe et que vous voulez juste retourner à la sécurité..
# Ignore le commit qui a causé le conflit git rebase --skip # Abandonne toute la rebase et revient à la planche à dessin git rebase --abort
Jusqu'à présent, nous utilisons seulement git rebase
déplacer des branches, mais c'est beaucoup plus puissant que cela. En passant le -je
drapeau, vous pouvez commencer une session de rebasage interactive. Le rebasage interactif vous permet de définir précisément comment chaque validation sera déplacée vers la nouvelle base. Cela vous donne la possibilité de nettoyer l'historique d'une fonctionnalité avant de la partager avec d'autres développeurs..
Par exemple, supposons que vous ayez fini de travailler sur votre fonctionnalité
branche et vous êtes prêt à l'intégrer dans maîtriser
. Pour commencer une session de rebasage interactive, exécutez la commande suivante:
fonctionnalité git checkout git rebase -i master
Cela ouvrira un éditeur contenant tous les commits de fonctionnalité
qui sont sur le point d'être déplacés:
pick 5c43c2b [Description du commit le plus ancien] pick b8f3240 [Description du 2e commit le plus ancien] pick c069f4a [Description du coup le plus récent]
Cette liste définit ce que le fonctionnalité
branche va ressembler après la rebase. Chaque ligne représente un commit et le choisir
commande avant chaque hachage de validation définit ce qui va lui arriver pendant la base. Notez que les commits sont listés du plus ancien au plus récent. En modifiant cette liste, vous obtenez un contrôle complet sur l'historique de votre projet..
Si vous souhaitez modifier l'ordre des commits, réorganisez simplement les lignes. Si vous voulez changer le message d'un commit, utilisez le bouton reformuler
commander. Si vous voulez combiner deux commits, changez le choisir
commande à écraser
. Cela transférera tous les changements de ce commit dans celui qui le précède. Par exemple, si vous écrasez le deuxième commit dans la liste ci-dessus, le fonctionnalité
branche ressemblerait à ceci après la sauvegarde et la fermeture de l'éditeur:
le modifier
le commandement est particulièrement puissant. Quand il atteindra la validation spécifiée, Git mettra en pause la procédure de rebase, un peu comme lorsqu'il rencontre un conflit. Cela vous donne la possibilité de modifier le contenu du commit avec git commit --amend
ou même ajouter plus de commits avec la norme git ajouter
/git commit
commandes. Tous les nouveaux commits que vous ajoutez feront partie de la nouvelle branche..
Le reclassement interactif peut avoir un impact profond sur votre flux de travail de développement. Au lieu de craindre de diviser vos modifications en commits encapsulés, vous pouvez vous concentrer sur l'écriture de votre code. Si vous avez finalement commis ce qui devrait être un seul changement en quatre instantanés distincts, alors ce ne sera pas un historique de réécriture de problème avec git rebase -i
et les écraser tous en un seul engagement significatif.
Maintenant que vous avez compris git rebase
, nous pouvons parler de quand ne pas l'utiliser. En interne, le changement de base ne déplace pas les commits vers une nouvelle branche. Au lieu de cela, il crée de nouveaux commits contenant les modifications souhaitées. Dans cet esprit, le rebasement est mieux visualisé comme suit:
Après la rebase, les commits en fonctionnalité
aura différents hashes de commettre. Cela signifie que nous n'avons pas simplement repositionné une branche: nous avons littéralement réécrit l'historique de nos projets. Ceci est un effet secondaire très important de git rebase
.
Lorsque vous travaillez seul sur un projet, la réécriture de l'historique n'est pas un gros problème. Cependant, dès que vous commencez à travailler dans un environnement collaboratif, cela peut devenir très dangereux. Si vous réécrivez les commits que d’autres développeurs utilisent (par exemple, les commits sur le maîtriser
branche), on dirait que ces commits ont disparu la prochaine fois qu’ils tentent de tirer votre travail. Il en résulte un scénario confus qui est difficile à récupérer à partir de.
Dans cet esprit, vous ne devriez jamais réabaisser les commits qui ont été placés dans un référentiel public, à moins que vous ne soyez sûrs que personne n'a basé leur travail sur eux..
Ce tutoriel a présenté les deux cas d’utilisation les plus courants de git rebase
. Nous avons beaucoup parlé de déplacer les branches, mais gardez à l’esprit que le changement de base revient en réalité à contrôler l’historique de vos projets. Le pouvoir de réécrire s’engage après coup vous permet de vous concentrer sur vos tâches de développement au lieu de décomposer votre travail en instantanés isolés..
Notez que le rebasement est un ajout totalement facultatif à votre boîte à outils Git. Vous pouvez toujours faire tout ce dont vous avez besoin avec un bon vieux fusionner
commandes. En effet, cela est plus sûr car cela évite la possibilité de réécrire l'histoire publique. Cependant, si vous comprenez les risques, git rebase
peut être un moyen beaucoup plus propre d'intégrer les branches par rapport à la fusion des commits.