A partire con git 1.9 / 2.0 Q1 2014, non dovrà contrassegnare la provenienza ramo precedente prima rebasing sul ramo monte riscritto, come descritto in Aristotele Pagaltzis 's risposta :
See commettere 07d406b e commettere d96855f :
Dopo aver lavorato sul topic
ramo creato con git checkout -b topic origin/master
, la storia del ramo di monitoraggio remoto origin/master
potrebbe essere stata riavvolta e ricostruita, portando a una storia di questa forma:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
dove origin/master
usato per indicare a commit B3
, B2
, B1
e ora punta a B
, e la vostra topic
filiale è stato avviato su di esso indietro quando origin/master
era a B3
.
Questa modalità utilizza il reflog di origin/master
per trovare B3
come punto di biforcazione, in modo che topic
possa essere ribasato in cima a aggiornatoorigin/master
da:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
Ecco perché il git merge-base
comando ha una nuova opzione:
--fork-point::
Trova il punto in cui un ramo (o qualsiasi storia che porta a <commit>
) si è biforcato da un altro ramo (o qualsiasi riferimento) <ref>
.
Questo non si limita a cercare l'antenato comune dei due commit, ma tiene anche conto del reflog di <ref>
per vedere se la storia che porta a <commit>
biforcarsi da una precedente incarnazione del ramo<ref>
.
Il git pull --rebase
comando " " calcola il punto di biforcazione del ramo che viene ribasato usando le voci reflog del base
ramo " " (tipicamente un ramo di tracciamento remoto) su cui si basava il lavoro del ramo, al fine di far fronte al caso in cui la "base" il ramo è stato riavvolto e ricostruito.
Ad esempio, se la cronologia assomiglia a dove:
- la punta attuale del "
base
" ramo è a B
, ma in precedenza fetch ha osservato che la sua punta usato per essere B3
e poi B2
e poi B1
prima di arrivare alla corrente impegnarsi, e
- il ramo che viene ribasato sull'ultima "base" è basato sul commit
B3
,
si cerca di trovare B3
passando attraverso l'uscita di " git rev-list --reflog base
" (vale a dire B
, B1
, B2
, B3
) finché non trova un commit che è un antenato della punta corrente " Derived (topic)
".
Internamente, possiamo get_merge_bases_many()
calcolarlo con una sola volta.
Vorremmo un merge-base between Derived
e un merge commit fittizio che risulterebbe unendo tutti i suggerimenti storici di " base (origin/master)
".
Quando esiste un commit di questo tipo, dovremmo ottenere un singolo risultato, che corrisponde esattamente a una delle voci di reflog di " base
".
Git 2.1 (Q3 2014) aggiungerà rendere questa funzionalità più robusta a questo: vedere commit 1e0dacd di John Keeping ( johnkeeping
)
gestire correttamente lo scenario in cui abbiamo la seguente topologia:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
dove:
B'
è una versione fissa di B
che non è identica alla patch B
;
C*
e D*
sono identici alla patch C
e D
rispettivamente e sono in conflitto testuale se applicati nell'ordine sbagliato;
E
dipende testualmente da D
.
Il risultato corretto git rebase master dev
è che B
è identificato come forcella punto dev
e master
, in modo che C
, D
, E
sono i commit che devono essere riprodotti su master
; ma C
e D
sono identici alla patch C*
e D*
e quindi possono essere eliminati, in modo che il risultato finale sia:
o --- B' --- C* --- D* --- E <- dev
Se il fork-point non viene identificato, il prelievo B
su un ramo contenente B'
risultati in un conflitto e se i commit identici alla patch non sono identificati correttamente, il prelievo C
su un ramo contenente D
(o equivalentemente D*
) si traduce in un conflitto.
La " --fork-point
" modalità di " git rebase
" è regredita quando il comando è stato riscritto in C nell'era 2.20, che è stato corretto con Git 2.27 (Q2 2020).
Vedi commit f08132f (09 dic 2019) di Junio C Hamano ( gitster
) .
(Fuso da Junio C Hamano - gitster
- in commit fb4175b , 27 marzo 2020)
rebase
: --fork-point
correzione della regressione
Firmato da: Alex Torok
[jc: rinnovato la correzione e utilizzato i test di Alex]
Autografato da: Junio C Hamano
" git rebase --fork-point master
" funzionava bene, come si chiamava internamente " git merge-base --fork-point
" che sapeva come gestire il refname breve e lo dwim al refname completo prima di chiamare la get_fork_point()
funzione sottostante .
Questo non è più vero dopo che il comando è stato riscritto in C, poiché la sua chiamata interna fatta direttamente a get_fork_point()
non dwim un breve ref.
Sposta la logica "dwim the refname" alla logica refname completa "usata in" git merge-base "alla get_fork_point()
funzione sottostante , in modo che l'altro chiamante della funzione nell'implementazione di" git rebase "si comporti allo stesso modo per correggere questa regressione.