Quando useresti le diverse strategie di unione git?


430

Dalla pagina man su git-merge, ci sono una serie di strategie di unione che puoi usare.

  • risoluzione - Questo può risolvere solo due teste (cioè il ramo corrente e un altro ramo da cui hai estratto) usando l'algoritmo di unione a 3 vie. Cerca di rilevare attentamente le ambiguità di unione incrociate ed è generalmente considerato sicuro e veloce.

  • ricorsivo - Questo può risolvere solo due teste usando l'algoritmo di unione a 3 vie. Quando ci sono più antenati comuni che possono essere utilizzati per l'unione a 3 vie, crea un albero unito degli antenati comuni e lo utilizza come albero di riferimento per l'unione a 3 vie. È stato segnalato che ciò comporta un minor numero di conflitti di unione senza causare errori di fusione da parte di test eseguiti su commit di unione effettivi tratti dalla cronologia di sviluppo del kernel Linux 2.6. Inoltre, questo può rilevare e gestire le fusioni che coinvolgono i nomi. Questa è la strategia di unione predefinita quando si estrae o unisce un ramo.

  • polpo - Questo risolve più del caso a due teste, ma si rifiuta di fare l'unione complessa che richiede una risoluzione manuale. È principalmente pensato per essere usato per raggruppare insieme le teste di rami di argomenti. Questa è la strategia di unione predefinita quando si estraggono o si uniscono più rami.

  • nostra - Questo risolve un numero qualsiasi di teste, ma il risultato della fusione è sempre la testa del ramo corrente. È pensato per essere utilizzato per sostituire la vecchia storia di sviluppo dei rami laterali.

  • subtree - Questa è una strategia ricorsiva modificata. Quando si uniscono gli alberi A e B, se B corrisponde a una sottostruttura di A, B viene prima regolato per abbinare la struttura ad albero di A, invece di leggere gli alberi allo stesso livello. Questa regolazione viene eseguita anche sull'albero degli antenati comune.

Quando devo specificare qualcosa di diverso rispetto al valore predefinito? Per quali scenari sono i migliori?

Risposte:


305

Non ho familiarità con la risoluzione, ma ho usato gli altri:

Ricorsivo

Ricorsivo è l'impostazione predefinita per le fusioni non a avanzamento rapido. Conosciamo tutti bene quello.

Polpo

Ho usato il polpo quando ho avuto diversi alberi che dovevano essere uniti. Lo vedi in progetti più grandi in cui molte filiali hanno avuto uno sviluppo indipendente ed è tutto pronto per riunirsi in un'unica testa.

Un ramo di polpo unisce più teste in un unico commit, purché possa farlo in modo pulito.

Per esempio, immagina di avere un progetto che ha un master e quindi tre rami in cui unire (chiamali a, b e c).

Una serie di fusioni ricorsive sarebbe simile a questa (si noti che la prima unione è stata un avanzamento rapido, poiché non ho forzato la ricorsione):

serie di fusioni ricorsive

Tuttavia, una singola fusione di polpo sarebbe simile a questa:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

fusione di polpo

Nostro

Il nostro == Voglio tirare un'altra testa, ma buttare via tutte le modifiche introdotte dalla testa.

Ciò mantiene la storia di un ramo senza alcun effetto del ramo.

(Leggi: Non vengono nemmeno esaminati i cambiamenti tra quei rami. I rami vengono semplicemente uniti e non viene fatto nulla ai file. Se vuoi unire l'altro ramo e ogni volta c'è la domanda "la nostra versione del file o il loro versione "puoi usare git merge -X ours)

sottostruttura

Sottotree è utile quando si desidera unire un altro progetto in una sottodirectory del progetto corrente. Utile quando si dispone di una libreria che non si desidera includere come sottomodulo.


1
Quindi l'unico vero vantaggio di Ocotopus è quello di ridurre il numero di commit di fusione nell'albero?
Otto

60
Non è necessario specificare la strategia di unione polpo : viene utilizzata automaticamente se si uniscono più di due rami ( git merge A B ...).
Jakub Narębski,

Ci scusiamo per essere fuori tema, ma qual è lo strumento con cui hai realizzato quegli screenshot? Sembra una visualizzazione davvero fantastica / carina della storia del ramo ...
Bernd Haug,

4
gitg per quelli su ambiente Linux.
Akash Agrawal,

2
Questo suggerimento -X oursè fantastico, mi ha fatto risparmiare un'ora di lavoro.
Michael,

49

In realtà le uniche due strategie che vorresti scegliere sono le nostre se vuoi abbandonare i cambiamenti apportati per ramo, ma mantieni il ramo nella storia e sottrai se stai unendo progetto indipendente nella sottodirectory di superproject (come 'git-gui' in ' git 'repository).

la fusione polpo viene utilizzata automaticamente quando si uniscono più di due rami. la risoluzione è qui principalmente per ragioni storiche e per quando si è colpiti da casi angolari di strategia di unione ricorsiva .


Ho dovuto scegliere 'risolvere' invece del predefinito 'ricorsivo' per una fusione a due teste che aveva errori fatali di git-write-tree. La strategia "Risolvi" si è fusa perfettamente. Potrebbe aver avuto a che fare con lo spostamento di molti file nel ramo da unire.
Thaddeusmt,

@thaddeusmt: interessante. Potresti, se possibile, pubblicare segnalazioni di bug su questo fallimento della strategia di unione "ricorsiva" nella git mailing list? Grazie in anticipo.
Jakub Narębski,

@ JakubNarębski Non sono sicuro di come mettere insieme abbastanza informazioni per presentare una segnalazione di bug significativa, sono un n00b con Git, mi dispiace. Come menziono nella mia risposta qui ( stackoverflow.com/a/10636464/164439 ) la mia ipotesi è che abbia a che fare con me duplicando le modifiche in entrambi i rami e "risolvere" fa un lavoro migliore nel saltare le modifiche duplicate.
Thaddeusmt,

@ JakubNarębski ormai puoi anche scegliere il loro , che è secondo il manuale "l'opposto del nostro . Il loro non è né scelto automaticamente per te. Che tu possa aggiornare leggermente il tuo anwser, aggiungendo la loro opzione
SebNag

3
@SebTu: non esiste una theirsstrategia di unione (ovvero --strategy=theirs), ma esiste theirsun'opzione per la recursivestrategia di unione predefinita (ovvero --strategy=recursive --strategy-option=theirs, o solo -Xtheirs).
Jakub Narębski,

23

Strategia di unione "Risolvi" vs "Ricorsiva"

La ricorsiva è l'attuale strategia a due teste predefinita, ma dopo alcune ricerche ho finalmente trovato alcune informazioni sulla strategia di unione "risoluzione".

Tratto dal libro O'Reilly Version Control with Git ( Amazon ) (parafrasato):

Inizialmente, "risolvere" era la strategia predefinita per le fusioni di Git.

In situazioni di unione incrociata, dove esiste più di una possibile base di unione, la strategia di risoluzione funziona in questo modo: scegli una delle possibili basi di unione e spera per il meglio. Questo in realtà non è così male come sembra. Si scopre spesso che gli utenti hanno lavorato su diverse parti del codice. In tal caso, Git rileva che sta rimediando ad alcune modifiche già in atto e salta le modifiche duplicate, evitando il conflitto. Oppure, se si tratta di lievi modifiche che causano conflitti, almeno il conflitto dovrebbe essere facile da gestire per lo sviluppatore.

Ho unito con successo gli alberi usando la "risoluzione" non riuscita con la strategia ricorsiva predefinita. Stavo ricevendo fatal: git write-tree failed to write a treeerrori e grazie a questo post sul blog ( mirror ) ho provato "-s resolver", che ha funzionato. Non sono ancora del tutto sicuro del perché ... ma penso che sia stato perché ho avuto modifiche duplicate in entrambi gli alberi e ho risolto "saltandole" correttamente.


Sto usando l'unione a 3 vie (p4merge) e ho avuto dei conflitti scritti nel file .BASE quando l'unione ricorsiva non è riuscita. In questo caso è stato utile ricorrere alla strategia di risoluzione.
mrzl,


-2

Poiché le risposte sopra riportate non mostrano tutti i dettagli della strategia. Ad esempio, qualche risposta manca i dettagli circa l'importazione resolvedi opzione e il recursiveche ha molte opzioni secondarie come ours, theirs, patience, renormalize, etc.

Pertanto, consiglierei di visitare la gitdocumentazione ufficiale che spiega tutte le possibili caratteristiche:

https://git-scm.com/docs/merge-strategies

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.