Git Cherry-pick vs Merge Workflow


302

Supponendo che io sia il manutentore di un repository e che desideri estrarre le modifiche da un collaboratore, ci sono alcuni possibili flussi di lavoro:

  1. I cherry-pickogni impegno dal telecomando (in ordine). In questo caso git registra il commit come non correlato al ramo remoto.
  2. Io mergeil ramo, inserendo tutte le modifiche e aggiungendo un nuovo commit "conflitto" (se necessario).
  3. I mergeogni impegno dal ramo remoto singolarmente (sempre in ordine), permettendo conflitti da registrare per ogni commit, anziché raggruppati tutti insieme come uno.
  4. Per completezza, potresti fare una rebase(stessa cherry-pickopzione?), Tuttavia la mia comprensione è che ciò può causare confusione per il contributore. Forse questo elimina l'opzione 1.

In entrambi i casi 2 e 3, git registra la cronologia delle ramificazioni dei commit, diversamente da 1.

Quali sono i pro e contro tra l'utilizzo di uno cherry-picko dei mergemetodi descritti? La mia comprensione è che il metodo 2 è la norma, ma ritengo che la risoluzione di un commit di grandi dimensioni con un'unica fusione "conflitto" non sia la soluzione più pulita.

Risposte:


297

Entrambi rebase(e cherry-pick) e mergehanno i loro vantaggi e svantaggi. Io discuto mergequi, ma vale la pena capirli entrambi. (Cerca qui una risposta alternativa e ben argomentata che elenca i casi in cui rebaseè preferito.)

mergeè preferito sopra cherry-picke rebaseper un paio di motivi.

  1. Robustezza . L'identificatore SHA1 di un commit lo identifica non solo in sé e per sé, ma anche in relazione a tutti gli altri commit che lo precedono. Ciò offre una garanzia che lo stato del repository in un dato SHA1 è identico per tutti i cloni. Non c'è (in teoria) alcuna possibilità che qualcuno abbia fatto quello che sembra lo stesso cambiamento, ma in realtà sta corrompendo o dirottando il tuo repository. Puoi scegliere con cura le singole modifiche e sono probabilmente le stesse, ma non hai alcuna garanzia. (Come problema secondario minore, i nuovi commit selezionati per ciliegia occuperanno spazio extra se qualcun altro sceglierà nuovamente lo stesso commit, poiché entrambi saranno presenti nella cronologia anche se le copie funzionanti finiranno per essere identiche.)
  2. Facilità d'uso . Le persone tendono a comprendere il mergeflusso di lavoro abbastanza facilmente. rebasetende ad essere considerato più avanzato. È meglio capire entrambi, ma le persone che non vogliono essere esperti nel controllo delle versioni (che nella mia esperienza ha incluso molti colleghi che sono dannatamente bravi in ​​quello che fanno, ma non vogliono passare il tempo extra) hanno una vita più facile il tempo si sta solo fondendo.

Anche con un flusso di lavoro pesantemente unito rebasee cherry-picksono ancora utili per casi particolari:

  1. Un aspetto negativo mergeè la storia ingombra. rebaseimpedisce a una lunga serie di commit di essere sparpagliati nella tua storia, come accadrebbe se ti unissi periodicamente ai cambiamenti degli altri. Questo è in effetti il ​​suo scopo principale mentre lo uso. Quello di cui vuoi stare molto attento, non è mai rebasecodificare che hai condiviso con altri repository. Una volta che è stato commesso un commit, pushqualcun altro potrebbe essersi impegnato al di sopra di esso, e il rebasing nella migliore delle ipotesi causerà il tipo di duplicazione discusso sopra. Nel peggiore dei casi, si può finire con un repository molto confuso e errori impercettibili che impiegheranno molto tempo a scappare.
  2. cherry-pick è utile per campionare un piccolo sottoinsieme di modifiche da un ramo di argomento che in pratica hai deciso di scartare, ma hai capito che ci sono un paio di pezzi utili su.

Per quanto riguarda preferire la fusione di molti cambiamenti su uno: è solo molto più semplice. Può diventare molto noioso fare fusioni di singoli changeset quando inizi ad averne molti. La risoluzione di fusione in git (e in Mercurial e in Bazaar) è molto buona. Non incontrerai grossi problemi unendo anche rami lunghi per la maggior parte del tempo. Generalmente unisco tutto in una volta e solo se ho un gran numero di conflitti, eseguo il backup e rieseguo il processo di unione frammentaria. Anche allora lo faccio in grossi pezzi. Come esempio molto reale, ho avuto un collega che aveva avuto 3 mesi di modifiche da unire e ho avuto circa 9000 conflitti in 250000 righe di codice. Quello che abbiamo fatto a correzione è fare vale la fusione di un mese alla volta: i conflitti non si accumulano in modo lineare, e farlo a pezzi risultati in lontanomeno di 9000 conflitti. Era ancora molto lavoro, ma non tanto quanto provare a farlo un impegno alla volta.


1
In realtà, in teoria c'è la possibilità che Mallory possa corrompere il tuo repository creando commit con lo stesso SHA1 ma con contenuti diversi, probabilmente non accadrà mai in pratica. :)
Bombe,

1
Ah :) Volevo dire "in teoria le probabilità sono così basse che puoi fare affidamento sul fatto che non accada", ma hai ragione che legge topsy turvy.
quark,

Cosa ne pensi di "merge --squash"?
cmcginty,

@Bombe Se Mallory vuole avere successo, dovrebbe costruire specificamente il commit originale e il secondo commit con lo stesso SHA1. Quindi un'altra domanda potrebbe essere: quali sono le probabilità che appaiano due (in qualche modo) falsi e tu non te ne accorgi? ;)
João Portela,

64
9000 conflitti? Lasciai il mio lavoro e diventavo un guardiano delle api.
Sebastian Patten,

95

A mio avviso, la raccolta delle ciliegie dovrebbe essere riservata a rare situazioni in cui è richiesta, ad esempio se hai fatto qualche correzione direttamente sul ramo "principale" (tronco, ramo di sviluppo principale) e poi hai capito che dovrebbe essere applicato anche a "manutenzione" '. È necessario basare il flusso di lavoro su merge o rebase (o "git pull --rebase").

Ricorda che il commit selezionato o modificato in base alla ciliegia è diverso dal punto di vista di Git (ha un identificatore SHA-1 diverso) rispetto all'originale, quindi è diverso dal commit nel repository remoto. (Rebase di solito può occuparsene, in quanto controlla l'ID patch, ovvero le modifiche, non un ID commit).

Anche in git puoi unire più rami contemporaneamente: la cosiddetta fusione di polpo . Nota che l'unione dei polpi deve riuscire senza conflitti. Tuttavia potrebbe essere utile.

HTH.


19
+1 per il punto in cui rebase / cherry-picking "copia" effettivamente i commit e quindi perde il collegamento al commit originale.
Studgeek,

1
Usiamo cherry-pick in questo modo, esclusivamente per spostare commit per correzioni di bug (forse funzionalità MOLTO PICCOLE) in un ramo di rilascio esistente per preparare una patch. Le funzionalità che si estendono su più commit generalmente garantiscono di entrare in un ramo di rilascio basato su master.
foxxtrot,

3
@foxxtrot: Un'altra soluzione è quella di creare un ramo separato per un bugfix, basato sul commit più vecchio che mostra questo bug, e unirlo in 'maint' e in 'master' ... anche se in questo caso devi sapere che detto bugfix si applica ad entrambi i rami.
Jakub Narębski,

4
@Jakub Due comandi indispensabili per creare e unire un ramo bugfix: git blametrovare il commit che ha introdotto il bug e git branch --containsdeterminare dove unire il ramo. Descritto più in dettaglio in questo post
gcbenison,

-10

Rebase e Cherry-pick è l'unico modo per mantenere pulita la cronologia dei commit. Evitare di utilizzare l'unione ed evitare la creazione di conflitti di unione. Se stai usando gerrit, imposta un progetto su Unisci, se necessario, e un progetto su Cherry-Pick Mode e prova te stesso.


non è chiaro come questo risponda alla domanda, forse alcuni esempi porterebbero un po 'di luce.
Adrian Nasui,

1
Il fatto che la tua storia sembrerebbe chiara non implica che sarebbe più facile da capire.
nicolimo86,

La fusione è il solito modo di avere una storia pulita. Cherry-pick e rebase viene utilizzato principalmente per situazioni in cui è necessario modificare la cronologia. Ciò significa che la fusione dovrebbe essere sempre la prima scelta. Perché rebase è cambiato, com'è molto pericoloso quando si lavora con telecomandi e più persone.
Radon8472,

Questo ragazzo qui merita una medaglia. Sa che continuerà a ricevere voti negativi ma è la risposta giusta. Complimenti.
PW Kad,

Mi dispiace non ho visto questi commenti fino ad ora, per favore provalo nel tuo ambiente di test prima di concludere e fai quello che funziona per te! Ho circa 600 sviluppatori che contribuiscono a più rami di prodotti, non mi interessa cosa fanno gli sviluppatori nell'area di lavoro locale, quando viene inviata una modifica per l'integrazione dovrebbe essere in grado di sviluppare il ramo o talvolta rilasciare o risolvere il problema. Cordiali saluti ... Uso Gerrit.
Nagaraj Magadum,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.