Git rebase: commit select in modalità fork-point

Leggendo la documentazione di git rebase e git merge-base man:

Dopo aver lavorato sul ramo dell’argomento creato con git checkout -b topic origine / master, la cronologia dell’origine / master del ramo di tracciamento remoto potrebbe essere stata riavvolta e ricostruita, portando a una cronologia di questa forma:

  o---B1 / ---o---o---B2--o---o---o---B (origin/master) \ B3 \ Derived (topic) 

dove origine / padrone ha usato per indicare i commit B3, B2, B1 e ora punta a B, e il ramo dell’argomento è stato avviato sopra di esso quando Origin / Master era in B3. Questa modalità utilizza il reflog dell’origine / master per trovare B3 come punto di biforcazione, in modo che l’argomento possa essere ridefinito sopra l’origine / master aggiornato per:

 $ fork_point=$(git merge-base --fork-point origin/master topic) $ git rebase --onto origin/master $fork_point topic 

$fork_point sarà (se ho capito bene) essere l’object commit B3 , e quindi il commit B3..topic sarà rebasato su origin/master ramo origin/master .

Q1 Perché è utile omettere il commit di B3 ? I commit del topic branch sono costruiti sopra il commit di B3 , quindi ometterlo significherebbe che le sue modifiche sarebbero quindi mancanti nella storia del ramo di origin/master . Rialzando il commit di B3 e il ramo topic si otterrebbe una cronologia più pulita, vero?

Q2 Qualcuno può colbind / descrivere brevemente casi d’uso pratico dell’opzione --fork-point nel stream di lavoro git?

Sei corretto che $fork_point sarà B3 .

Credo che l’intento qui sia di omettere B3 come “non il tuo impegno”.

Penso che il diagramma che la gente di Git ha disegnato qui non sia così buono. Ecco come vorrei ridisegnarlo e riscriverlo senza cambiarlo troppo (anche se probabilmente dovrei semplicemente riscrivere ogni commit in ogni caso).


Si inizia con la clonazione (o l’aggiornamento in altro modo) di un repository ( origin ) il cui grafico termina con commit B3 , e si crea un ramo argomento e si esegue qualche commit (s):

 ...--o---F---B3 <-- origin/master \ G <-- topic 

Nel tempo, con git fetch -es e git commit s aggiuntivi, il tuo grafico di commit ora si presenta così:

 ...--o---F---B3--B2--B1 <-- origin/master \ G---H---I <-- topic 

Ma, all'improvviso, dopo un altro git fetch , il tuo grafico di commit ora assomiglia a questo:

  o---B1' <-- origin/foo / ...o---F---B2'-o---o---o---B <-- origin/master \ B3--G---H---I <-- topic 

Cioè, Git ora penserebbe che il commit di B3 appartiene al tuo ramo dell'argomento, quando in realtà il tuo lavoro inizia con commit G Le persone che possiedono il repository di origin hanno dichiarato, in effetti, che il commit di B3 è terribile e dovrebbe essere gettato via. (Hanno tenuto una copia di B2 come B2' sul loro master e una di B1 come B1' sul loro foo .)

Se si git rebase semplicemente git rebase , si copierà il commit originale B3 nella nuova copia B3' (mentre si copia anche GHI ):

  o---B1' <-- origin/foo / ...o---F---B2'-o---o---o---B <-- origin/master \ B3'-G'--H'--I' <-- topic 

ma preferiresti invece:

  o---B1' <-- origin/foo / ...o---F---B2'-o---o---o---B <-- origin/master \ G'--H'--I <-- topic 

Affinché git rebase faccia ciò, devi istruire Git a localizzare il commit B3 . Il tuo reflog per origin/master ha tutte le F , B3 , B2 e B1 in esso (sotto almeno una voce di reflog, incluso in questo caso origin/[email protected]{1} ), mentre il tuo topic ha F e B3 , ma non B2B1 , anche in questo. Pertanto --fork-point sceglie B3 come il commit condiviso più recente (tip-most), piuttosto che F


La frase / idea chiave qui è che gli autori del repository upstream intendevano scartare completamente il commit di B3 .

(Come si dovrebbe sapere per certo è un po 'un mistero. Potrebbe non essere ovvio che B2' e B1' sono copie, se il ribasso richiesto, ad esempio, scartando un file che non avrebbe mai dovuto essere commesso-ed era in B1 , motivo per cui anche B1 stato scartato: il fatto che questo file sia ora omesso in B2' e B3' li rende non equivalenti alle patch, quindi non ovviamente copie.)

(Nota che anche il tuo master punta ancora a B3 !)