A partir de git 1.9 / 2.0 Q1 2014, vous ne devez marquer l' origine précédente de la branche avant rebasage sur la branche amont réécrite, comme décrit dans Aristote Pagaltzis de réponse :
Voir commit 07d406b et engage d96855f :
Après avoir travaillé sur la topic
branche créée avec git checkout -b topic origin/master
, l'historique de la branche de suivi à distance a origin/master
peut-être été rembobiné et reconstruit, conduisant à un historique de cette forme:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
où origin/master
utilisé pour point commits B3
, B2
, B1
et maintenant il pointe à B
, et votre topic
branche a commencé au - dessus de ce retour en origin/master
était à B3
.
Ce mode utilise le reflog de origin/master
pour trouver B3
comme point de fourche, de sorte que le topic
peut être rebasé au-dessus de la miseorigin/master
à jour par:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
C'est pourquoi la git merge-base
commande a une nouvelle option:
--fork-point::
Trouvez le point auquel une branche (ou tout historique qui mène à <commit>
) a bifurqué d'une autre branche (ou de toute référence) <ref>
.
Cela ne cherche pas seulement l'ancêtre commun des deux commits, mais prend également en compte le reflog de <ref>
pour voir si l'histoire menant à <commit>
bifurqué d'une incarnation antérieure de la branche<ref>
.
La git pull --rebase
commande " " calcule le point de branchement de la branche rebasée en utilisant les entrées reflog de la base
branche " " (généralement une branche de suivi à distance) sur laquelle le travail de la branche était basé, afin de faire face au cas où la "base" branche a été rembobinée et reconstruite.
Par exemple, si l'historique ressemblait à où:
- la pointe actuelle de la
base
branche " " est à B
, mais plus tôt fetch a observé que sa pointe était B3
avant B2
et puis B1
avant d'arriver au commit actuel, et
- la branche rebasée au-dessus de la dernière "base" est basée sur commit
B3
,
il essaie de trouver B3
en passant par la sortie de « git rev-list --reflog base
» (c. -à B
, B1
, B2
, B3
) jusqu'à ce qu'il trouve un commettras qui est un ancêtre de l'actuelle pointe « Derived (topic)
».
En interne, nous get_merge_bases_many()
pouvons calculer cela en une seule fois.
Nous voudrions une base de fusion entre Derived
et un commit de fusion fictif qui résulterait de la fusion de tous les conseils historiques de " base (origin/master)
".
Lorsqu'un tel commit existe, nous devrions obtenir un seul résultat, qui correspond exactement à l'une des entrées reflog de " base
".
Git 2.1 (Q3 2014) ajoutera pour rendre cette fonctionnalité plus robuste à ceci: voir commit 1e0dacd par John Keeping ( johnkeeping
)
gérer correctement le scénario où nous avons la topologie suivante:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
où:
B'
est une version corrigée de B
qui n'est pas identique au patch B
;
C*
et D*
sont identiques au patch C
et D
respectivement et sont en conflit textuellement s'ils sont appliqués dans le mauvais ordre;
E
dépend textuellement de D
.
Le résultat correct de git rebase master dev
est - ce que B
est identifié comme le point fourche dev
et master
, de sorte que C
, D
, E
sont les commits qui doivent être rejoué sur master
; mais C
et D
sont identiques au patch avec C*
and D*
et peuvent donc être supprimés, de sorte que le résultat final est:
o --- B' --- C* --- D* --- E <- dev
Si le point de bifurcation n'est pas identifié, alors choisir B
une branche contenant B'
entraîne un conflit et si les commits identiques au correctif ne sont pas correctement identifiés, alors choisir C
une branche contenant D
(ou de manière équivalente D*
) entraîne un conflit.
Le " --fork-point
" mode de " git rebase
" a régressé lorsque la commande a été réécrite en C à l'ère 2.20, ce qui a été corrigé avec Git 2.27 (T2 2020).
Voir commit f08132f (09 décembre 2019) par Junio C Hamano ( gitster
) .
(Fusionné par Junio C Hamano - gitster
- dans commit fb4175b , 27 mars 2020)
rebase
: --fork-point
correction de régression
Signé par: Alex Torok
[jc: remanié le correctif et utilisé les tests d'Alex]
Signé par: Junio C Hamano
" git rebase --fork-point master
" fonctionnait bien, comme il l'appelait en interne " git merge-base --fork-point
" qui savait comment gérer le nom de référence court et le dwimer avec le nom complet avant d'appeler la get_fork_point()
fonction sous-jacente .
Ce n'est plus vrai après la réécriture de la commande en C, car son appel interne effectué directement à get_fork_point()
ne dwim une courte référence.
Déplacez la logique "dwim the refname vers le refname complet" qui est utilisée dans "git merge-base" vers la get_fork_point()
fonction sous-jacente , de sorte que l'autre appelant de la fonction dans l'implémentation de "git rebase" se comporte de la même manière pour corriger cette régression.