2015-04-27 28 views
7

Versione corta:
Come passare dal grafico di sinistra a quello di destra. Inoltre, ho bisogno di cancellare manualmente i commit duplicati (root2, a ', b') o il GC li potenzierà ad un certo punto in futuro? before-afterRipara cronologia git con commit duplicati

Versione lunga:
causa di un brutto CVS a git porta ho finito con due storie si alternano nello stesso repo quando ho importato branch_1 da CVS Quando il Maestro era stato già creato in git. Come si può vedere, ci sono commit di branch_1 che sono unici, ma ce ne sono altri che sono duplicati. Qual è il modo più semplice per risolvere questo problema?

Ho alcune idee ma non sono sicuro di come eseguirle. Uno sarebbe quello di rimuovere branch_1 del tutto e ricominciare, ma non so come far riconoscere git che root1 e root2 sono gli stessi in modo che tutte le patch vengano applicate sulla stessa linea. Un'altra idea sarebbe quella di rebase f, g, h su b e in qualche modo rimuovere root2, un ' e b'. Ma credo che, poiché non v'è alcun antenato comune, un rebase normale non funzionerà

In realtà, il duplicato impegna e impegna uniche del ramo sono centinaia in modo qualcosa di molto manuale non è buona

risposta

1

Nota che il rebase che stai chiedendo riscriverà gli hash di commit di tutti si impegna su branch_1. Sto usando b e b' per indicare gli hash di commit dei commit nella tua bella figura.

git checkout branch_1 
git rebase --onto b b' 

Questo corrisponde il seguente modulo di git rebase dalla pagina di manuale:

git rebase --onto <newbase> <upstream> 

Sulla base del manuale, di seguito verrà poi accadrà.

  1. Tutte le modifiche apportate da commit nel ramo corrente ma non in <upstream> vengono salvate in un'area temporanea.
  2. Il ramo corrente viene reimpostato su <upstream> o <newbase> se è stata fornita l'opzione --onto.
  3. I commit precedentemente salvati nell'area temporanea vengono quindi riapplicati al ramo corrente, uno alla volta, nell'ordine.
+0

IIUC, il modo in cui rebases il lavoro è ripetendo il commit nella branca corrente dal ** ultimo antenato comune ** tra i due rami. Nel mio caso non esiste un antenato comune. Quindi o fallirà o metterà * root2 * come figlio di * b *. In entrambi i casi è sbagliato. Mi sto perdendo qualcosa? – Hilikus

+1

@Hilikus, guarda 'man git-rebase' e ​​grep per l'opzione' --onto'. – merlin2011

+0

@Hilikus, ho citato le parti rilevanti del manuale. – merlin2011

2

Una possibilità è possibile provare per primo, che non è distruttiva, è quello di utilizzare un Graft Point:

# .git/info/grafts 
0000000f 0000000b 

sostituire quelli con i SHA1s di commettere f e b nel diagramma.

Questo cambiamento sarà non permanente, ma dovrebbe essere in grado di rivisto con:

git log --graph --all --decorate 

Se tutto sembra buono, è possibile eseguire git filter-branch di rendere tali modifiche permanenti.

Nota che, fino a quando non fai un git filter-branch e fai clic su questo, nessun altro vedrà queste modifiche. Questo potrebbe essere considerato una "caratteristica", dal momento che non costringerà nessun altro a dover fare una disordinata base del proprio lavoro. Questo in pratica aggiunge solo alcune informazioni extra che indicano strumenti come git-log e tali che, quando guardano il commit "f", dovrebbero fingere di avere un genitore di "b", senza effettivamente aggiornare l'oggetto commit per riflettere quello. La modifica del genitore di un oggetto commit cambia il suo SHA1, quindi vuol dire che il suo figlio commette deve essere aggiornato per puntare al nuovo SHA1, quindi ai loro figli, ecc.

+0

Lo consiglio su 'git rebase' perché conserva i contenuti (alberi) di entrambi i rami. 'git rebase' conserva le modifiche (diff). –

+0

@DietrichEpp vuoi dire che finirò col grafico sinistro ma con un margine extra da 'b' a' f'? Se questo è ciò che intendi per "preserva gli alberi", non lo voglio, dal momento che entrambi quegli alberi sono in realtà dei duplicati – Hilikus

+0

No, in pratica si finisce con il grafico a destra, ma lo fa senza riscrivere la tua cronologia . – pioto

Problemi correlati