Je ne peux pas comprendre le comportement de git rebase –onto

J’ai remarqué que les deux blocs de commandes git suivantes ont des comportements différents et je ne comprends pas pourquoi.

J’ai une twig A et B qui divergent avec un engagement

---BRANCH A-------COMMIT1----- \--BRANCH B-- 

Je veux rebaser la twig B sur le dernier A (et avoir le commit1 sur la twig B)

 ---BRANCH A-------COMMIT1----- \--BRANCH B-- 

Pas de problème si je le fais:

 checkout B rebase A 

Mais si je le fais:

 checkout B rebase --onto BA 

Cela ne marche pas du tout, rien ne se passe. Je ne comprends pas pourquoi les deux comportements sont différents.

Phpstorm git client utilise la deuxième syntaxe, et me semble donc complètement brisé, c’est pourquoi je demande ce problème de syntaxe.

tl; dr

La syntaxe correcte pour rebase B sur A utilisant git rebase --onto dans votre cas est la suivante:

 git checkout B git rebase --onto AB^ 

ou rebase B au-dessus de A à partir du commit qui est le parent de B référencé avec B^ ou B~1 .

Si vous êtes intéressé par la différence entre la git rebase et git rebase --onto lisez la suite.

Le Quick: git rebase

git rebase va rebaser la twig que vous avez extraite, référencée par HEAD , en plus du dernier commit accessible depuis mais pas de HEAD .
C’est le cas le plus courant de rebasage et sans doute celui qui nécessite moins de planification à l’avance.

  Before After A---B---C---F---G (branch) A---B---C---F---G (branch) \ \ D---E (HEAD) D---E (HEAD) 

Dans cet exemple, F et G sont des commits accessibles depuis la branch mais pas depuis HEAD . Dire git rebase branch prendra D , c’est-à-dire le premier commit après le sharepoint twigment, et le rebasera (c’est-à-dire changer son parent ) au-dessus du dernier commit accessible depuis la branch mais pas HEAD , c’est-à-dire G

The Precise: git rebase –onto avec 2 arguments

git rebase --onto vous permet de rebaser à partir d’un commit spécifique . Il vous permet de contrôler exactement ce qui est rebasé et où. Ceci est pour les scénarios où vous devez être précis.

Par exemple, imaginons que nous devons rebaser HEAD précisément au-dessus de F partir de E Nous ne souhaitons que mettre F dans notre twig de travail, mais en même temps, nous ne voulons pas conserver D car il contient des modifications incompatibles.

  Before After A---B---C---F---G (branch) A---B---C---F---G (branch) \ \ D---E---H---I (HEAD) E---H---I (HEAD) 

Dans ce cas, nous dirions git rebase --onto FD . Ça signifie:

Rebase le commit accessible depuis HEAD dont le parent est D au dessus de F

En d’autres termes, changez le parent de E de D à F La syntaxe de git rebase --onto est alors git rebase --onto .

Un autre scénario très pratique consiste à supprimer rapidement certains commits de la twig en cours sans avoir à effectuer de rebase interactive :

  Before After A---B---C---E---F (HEAD) A---B---F (HEAD) 

Dans cet exemple, afin de supprimer C et E de la séquence, vous diriez git rebase --onto BE , ou rebase HEAD au-dessus de B où l’ancien parent était E

Le chirurgien: git rebase –onto avec 3 arguments

git rebase --onto peut aller plus loin en termes de précision. En fait, il vous permet de rebaser une gamme arbitraire de commits sur une autre.

Voici un exemple:

  Before After A---B---C---F---G (branch) A---B---C---F---G (branch) \ \ D---E---H---I (HEAD) E---H (HEAD) 

Dans ce cas, nous voulons rebaser la plage exacte E---H sur F , en ignorant où HEAD pointe actuellement. Nous pouvons le faire en disant que git rebase --onto FDH , ce qui signifie:

Rebase la plage de commits dont le parent est D jusqu’à H en plus de F

La syntaxe de git rebase --onto avec une plage de commits devient alors git rebase --onto . L’astuce ici est de se rappeler que la validation référencée par est incluse dans la plage et deviendra la nouvelle HEAD après la fin de la réinitialisation.

C’est tout ce que vous devez savoir pour comprendre

 git rebase --onto   

Vous changez de parent sur un commit, mais vous ne fournissez pas le sha du commit, seulement le sha de son parent actuel.

En un git rebase --onto , git rebase --onto sélectionne une plage de commits et les rebase sur le commit donné en paramètre.

Lisez les pages de manuel relatives à git rebase , recherchez “on”. Les exemples sont très bons:

 example of --onto option is to rebase part of a branch. If we have the following situation: H---I---J topicB / E---F---G topicA / A---B---C---D master then the command git rebase --onto master topicA topicB would result in: H'--I'--J' topicB / | E---F---G topicA |/ A---B---C---D master 

Dans ce cas, vous indiquez à git de rebaser les commits de topicA à topicB au-dessus de master .

Car onto vous avez besoin de deux twigs supplémentaires. Avec cette commande, vous pouvez appliquer les commits de branchB basés sur branchA sur une autre twig, par exemple master . Dans l’exemple ci-dessous, branchB est basé sur branchA et vous souhaitez appliquer les modifications de branchB sur master sans appliquer les modifications de branchA .

 o---o (master) \ o---o---o---o (branchA) \ o---o (branchB) 

en utilisant les commandes:

 checkout master rebase --onto branchA branchB 

vous obtiendrez la hiérarchie d’engagement suivante.

  o'---o' (branchB) / o---o (master) \ o---o---o---o (branchA)