2012-06-20 10 views
6

Il nostro flusso di lavoro di sviluppo git è che i rami argomento vengono continuamente ridefiniti sull'ultimo master fino a quando non vengono uniti.Modifica cronologia di un ramo di argomento git che utilizza uniti per utilizzare le rebases

Tuttavia, un nuovo sviluppatore ha creato rami di argomenti in cui ha eseguito diverse fusioni di master nelle sue sezioni tematiche per mantenerle aggiornate.

A---B---C---D---E topic 
/ //
    F---G---H---I master 

Mentre unire questo ramo di argomento al master sarebbe perfettamente corretto, risulta in una cronologia molto caotica. Voglio convertire questi rami argomento in una storia ricalcolato lineare, pulita, che può essere fusa in modo pulito in matrimoniale con un unico --no-ff merge commettere cioè:

   A'---B'---E' topic 
      /
    F---G---H---I master 

Idealmente, ci sarebbe qualche git-fu che mi permettesse di fare il rebase, assumendo i commit sul ramo dell'argomento così com'è, mentre applica automaticamente le informazioni sulla risoluzione dei conflitti di fusione già disponibili nell'argomento merge commit come C e D.

So che posso semplicemente applicare la patch di "git" diff master..topic "e poi usare rebase per lavorare all'indietro e dividere manualmente la singola patch in singoli commit, ma esiste un approccio più semplice ed elegante?

Ho provato i comandi immediati git rebase e git rebase -p senza fortuna.

risposta

4

Ho trovato che il seguente processo sembra funzionare abbastanza bene, anche se non perfettamente. Potrebbero essere necessarie alcune risoluzioni minori in conflitto - vedi sotto.

  1. Assicurarsi che il ramo argomento è up-to-date con le ultime maestro facendo una fusione finale da maestro, se non già fatto:

    git checkout topic 
    git merge master 
    
  2. Semplificare la storia del ramo argomento da escluse le unioni:

    git log --no-merges 
    
  3. Dal registro di sopra, determinano il punto di diramazione (il commit su Master prima del primo ramo argomento commesso, che dovrebbe essere il commit F).

  4. Rebase ramo argomento su padrone, ignorando le unioni (che è il default, vale a dire non utilizzare l'opzione --preserve-merges/-p), risolvere eventuali conflitti.

    git checkout master 
    git rebase --onto HEAD F topic 
    

    ho scoperto che durante rebasing, spesso un conflitto sarebbe risultato in cui un file era in una "Entrambi Modified" stato di conflitto, ma non conteneva marcatori di conflitto, quindi un semplice git add e git rebase --continue era sufficiente per risolvere il conflitto e continua. Credo che Git stia usando la risoluzione precedente per risolvere i conflitti.

    Inoltre, in alcuni rami più complessi, saranno necessari più comandi o in alternativa è possibile utilizzare git cherry-pick per selezionare singoli commit. È sufficiente lavorare attraverso il registro indicato nel passaggio 2, ribadendo gli intervalli su HEAD e/o potenzialmente selezionando singoli commit secondo necessità.

  5. L'attuale HEAD dovrebbe ora rappresentare il ramo dell'argomento successivo.Verificare che il risultato corrisponda al ramo tema originale controllando che i risultati diff in nessuna uscita:

    git diff topic..HEAD 
    
  6. il capo al nome di argomento ramo ricalcolato:

    git checkout -b rebased-topic 
    
1

risposta di Raman praticamente ha funzionato per me, ma ho pensato di aggiungere ulteriori dettagli sul passaggio 4, il che è stato complicato per me ..

Ho avuto un repository che è stato più complicato, era come questo

 Q-R-S-T-U-V-W-X 
    // //
A-B-C-D-E-F-G-H-I-J-K 

Ho voluto questo:

     Q'-R'-S'-T'-U'-V'-W'-X' 
        /
A-B-C-D-E-F-G-H-I-J-K 

Quello che ha funzionato è stato quello di fare git rebase --onto HEAD Q R, poi git rebase --onto HEAD S U, in modo sostanzialmente afferrando le gamme di commit tra i luoghi dove sono fuse master per topic. Per tutto il tempo in cui lo stavo facendo, ero in stato di distacco, quindi non preoccuparti se lo vedi. Ci sono state alcune volte in cui ho avuto conflitti di fusione, ma erano tutti conflitti legittimi che mi sarei aspettato di vedere.

Infine, ho avuto un ramo che sembrava giusto (passaggio 6 nella risposta di Raman), ma per qualche motivo ho dovuto rebase sul master di nuovo per spostare effettivamente i commit. Non so perché dovevo farlo, ma è andato liscio.

Penso che farlo in questo modo sia sostanzialmente equivalente al cherry picking, quindi potrebbe essere più semplice farlo invece.

+0

Hmm, sei sicuro che sia davvero quello che volevi? S, V e X nel tuo grafico vedono essere commit di unione e quindi non dovrebbero essere presenti come S ', V' e X 'nello stato desiderato. A meno che non contenessero un mucchio di risoluzione del conflitto manuale, suppongo. – Raman

Problemi correlati