Quando useresti le diverse strategie di git merge?

Dalla pagina man di git-merge, ci sono un certo numero di strategie di unione che puoi usare.

  • solve – Questo può risolvere solo due teste (cioè il ramo corrente e un altro ramo da cui hai tirato) usando l’algoritmo di fusione a 3 vie. Cerca di individuare con attenzione le ambiguità di fusione incrociate ed è considerato generalmente sicuro e veloce.

  • ricorsivo – Questo può risolvere solo due teste usando l’algoritmo di fusione a 3 vie. Quando esistono 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 questo comporta un minor numero di conflitti di fusione senza causare mis-merges da test eseguiti su commit di merge effettivi presi dalla cronologia di sviluppo del kernel di Linux 2.6. Inoltre, questo può rilevare e gestire le unioni che coinvolgono i nomi. Questa è la strategia di unione predefinita quando si estrae o unisce un ramo.

  • polpo : risolve più di un caso a due teste, ma si rifiuta di eseguire un’unione complessa che richiede una risoluzione manuale. È principalmente pensato per essere utilizzato per raggruppare insieme teste di argomenti. Questa è la strategia di unione predefinita quando si estraggono o si uniscono più rami.

  • nostro – Questo risolve qualsiasi numero di teste, ma il risultato dell’unione è sempre l’attuale capo del ramo. È pensato per essere utilizzato per sostituire la vecchia cronologia di sviluppo dei rami laterali.

  • sottostruttura – Questa è una strategia ricorsiva modificata. Quando si uniscono gli alberi A e B, se B corrisponde a un sottoalbero di A, B viene prima regolato per adattarsi alla struttura ad albero di A, invece di leggere gli alberi allo stesso livello. Questa regolazione viene eseguita anche sull’albero degli antenati comuni.

Quando dovrei specificare qualcosa di diverso da quello predefinito? Per quali scenari è meglio scegliere?

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

Ricorsivo

Ricorsiva è l’impostazione predefinita per le unioni non a avanzamento rapido. Conosciamo tutti questo.

Polpo

Ho usato polpi 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 commit fintanto che può farlo in modo pulito.

Per esempio, immagina di avere un progetto con un master e quindi tre rami da 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... 

polpo si fondono

Nostro

La nostra == Voglio tirare un’altra testa, ma butta via tutte le modifiche introdotte dalla testa.

Ciò mantiene la storia di un ramo senza nessuno degli effetti del ramo.

(Leggi: Non sono nemmeno guardati i cambiamenti tra quei rami: i rami sono semplicemente uniti e non viene fatto nulla ai file. Se vuoi unirmi all’altro ramo e ogni volta c’è la domanda “la nostra versione del file o il loro versione “puoi usare git merge -X ours )

sottostruttura

Sottostruttura è utile quando si desidera unire in un altro progetto in una sottodirectory del progetto corrente. Utile quando hai una libreria che non vuoi includere come sottomodulo.

In realtà le uniche due strategie che vorrai scegliere sono le nostre se vuoi abbandonare i cambiamenti portati per ramo, ma mantenere il ramo nella storia e la sottostruttura se stai unendo un progetto indipendente nella sottodirectory del superproject (come ‘git-gui’ in ‘ git ‘repository).

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

Strategia di fusione “Risolvi” e “Ricorsiva”

Ricorsivo è l’attuale strategia a due teste predefinita, ma dopo alcune ricerche ho finalmente trovato alcune informazioni sulla strategia di unione “risoluzione”.

Tratto da O’Reilly book Version Control with Git ( Amazon ) (parafrasato):

Originariamente, “risoluzione” era la strategia predefinita per le fusioni di Git.

In situazioni di unione incrociata, in cui esiste più di una base di unione ansible, la strategia di risoluzione funziona in questo modo: scegli una delle possibili basi di unione e sperare per il meglio. Questo in realtà non è così male come sembra. Spesso si scopre che gli utenti hanno lavorato su diverse parti del codice. In tal caso, Git rileva che sta rimuovendo alcuni cambiamenti già in atto e ignora le modifiche duplicate, evitando il conflitto. Oppure, se queste sono piccole modifiche che causano conflitti, almeno il conflitto dovrebbe essere facile da gestire per lo sviluppatore.

Ho unito con successo gli alberi usando “resolve” che non ha funzionato con la strategia ricorsiva predefinita. Stavo diventando fatal: git write-tree failed to write a tree errori sugli fatal: git write-tree failed to write a tree , e grazie a questo post del blog ( mirror ) ho provato “-s resolve”, che ha funzionato. Non sono ancora del tutto sicuro del perché … ma penso che sia stato perché ho apportato modifiche doppie in entrambi gli alberi e ho risolto “saltati” correttamente.