Domanda

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

  1. IO cherry-pick ogni commit dal remoto (in ordine).In questo caso git registra il commit come non correlato al ramo remoto.
  2. IO merge il ramo, inserendo tutte le modifiche e aggiungendo un nuovo commit "conflitto" (se necessario).
  3. IO merge ogni commit dal ramo remoto individualmente (sempre in ordine), consentendo di registrare i conflitti per ciascun commit, invece di raggrupparli tutti insieme come uno solo.
  4. Per completezza, potresti fare a rebase (uguale a cherry-pick opzione?), tuttavia, da quanto mi risulta, ciò può causare confusione al contributore.Forse questo elimina l'opzione 1.

In entrambi i casi 2 e 3, git registra la cronologia dei rami dei commit, a differenza di 1.

Quali sono i pro e i contro nell'utilizzarli? cherry-pick O merge metodi descritti? La mia comprensione è che il metodo 2 è la norma, ma ritengo che risolvere un commit di grandi dimensioni con una singola unione di "conflitto" non sia la soluzione più pulita.

È stato utile?

Soluzione

Sia rebase (e cherry-pick) e merge hanno i loro vantaggi e svantaggi. Io sostengo per merge qui, ma vale la pena comprendere sia. (Guardate qui per un supplente, rispondere enumerare casi in cui rebase è preferito.)

merge è preferito rispetto cherry-pick e rebase per un paio di motivi.

  1. Robustezza . L'identificatore SHA1 di un commit identifica non solo in sé e per sé, ma anche in relazione alle tutti gli altri commit che lo precedono. Questo vi offre una garanzia che lo stato del repository in un dato SHA1 è identico in tutti i cloni. Non v'è (in teoria) alcuna possibilità che qualcuno ha fatto quello che sembra lo stesso cambiamento, ma in realtà è di rovinare o dirottamento del repository. È possibile cherry-pick nei singoli cambiamenti e che sono suscettibili lo stesso, ma non si ha garanzia. (Come un problema secondario minore i nuovi commit ciliegia raccolte saranno occupano spazio in più se qualcun altro ciliegio-picks nello stesso commettono ancora una volta, in quanto saranno entrambi presenti nella storia, anche se le vostre copie di lavoro finiscono per essere identica.)
  2. Facilità d'uso . Le persone tendono a capire il flusso di lavoro merge abbastanza facilmente. rebase tende ad essere considerato più avanzata. E 'meglio per capire entrambi, ma le persone che non vogliono essere esperti nel controllo di versione (che nella mia esperienza ha incluso molti colleghi che sono dannatamente bravo in quello che fanno, ma non vogliono spendere il tempo in più) hanno un più facile tempo solo la fusione.

Anche con un flusso di lavoro rebase merge-pesante e cherry-pick sono ancora utili per casi particolari:

  1. Uno svantaggio per merge è storia ingombra. rebase impedisce una lunga serie di commit di essere sparsi nella vostra storia, come lo sarebbero se periodicamente fuse nel cambiamenti degli altri. Questo è in realtà il suo scopo principale, come lo uso. Che cosa si vuole essere molto attenzione, non è mai a rebase codice che avete condiviso con altri repository. Una volta che un commit è pushed qualcun altro potrebbe aver commesso su di esso, e rebasing farà nel migliore dei casi sì che il tipo di duplicazione discusso in precedenza. Nel peggiore dei casi si può finire con un repository molto confuso e sottili errori ci vorrà molto tempo per scovare.
  2. cherry-pick è utile per il campionamento fuori un piccolo sottoinsieme di cambiamenti da un ramo argomento che hai sostanzialmente deciso di scartare, ma si rese conto ci sono un paio di pezzi utili su.

Per quanto riguarda preferendo fusione molti cambiamenti oltre un: è solo molto più semplice. Si può ottenere molto noioso di fare fonde dei singoli gruppi di modifiche una volta che si inizia ad avere un sacco di loro. La risoluzione unione in git (e in Mercurial e Bazaar) è molto molto buona. Non sarà incorrere in grossi problemi che si fondono anche lunghi rami maggior parte del tempo. Io in genere fondere tutto in una volta e solo se ottengo un gran numero di conflitti effettuare un backup e ri-eseguire la stampa frammentario. Anche allora lo faccio in grossi pezzi. Come un vero e proprio esempio ho avuto un collega che aveva 3 mesi di variazioni per unire, e ottenuto alcuni conflitti in 9000 250000 linea di codice di base. Quello che abbiamo fatto per risolvere è fare vale la fusione di un mese alla volta: i conflitti non si accumulano in modo lineare, e farlo a pezzi risultati in molto meno di 9000 i conflitti. Era ancora un sacco di lavoro, ma non tanto quanto cercare di farlo un commit alla volta.

Altri suggerimenti

A mio avviso la scelta della selezione dovrebbe essere riservata a rare situazioni in cui è richiesta, ad esempio se hai apportato alcune correzioni direttamente al ramo 'master' (trunk, ramo di sviluppo principale) e poi ti rendi conto che dovrebbe essere applicato anche a 'maint '.Dovresti basare il flusso di lavoro sull'unione o sul rebase (o "git pull --rebase").

Ricorda che il commit selezionato o ribasato è 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ò occuparsi di questo, poiché controlla l'ID della patch, ad es.le modifiche, non un ID di commit).

Anche in git puoi unire più rami contemporaneamente:così chiamato polpo si fondono.Tieni presente che l'unione di polpi deve avere successo senza conflitti.Tuttavia potrebbe essere utile.

HTH.

REBASE e cherry-pick è l'unico modo è possibile mantenere pulita commettere storia. Evitare l'uso di fusione ed evitare di creare conflitti di unione. Se si utilizza insieme Gerrit un progetto per unire, se necessario, e un progetto alla modalità di cherry-pick e provare voi stessi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top