Perché una fusione a 3 vie è vantaggiosa rispetto a una fusione a 2 vie?


165

Wikipedia afferma che un'unione a 3 vie è meno soggetta a errori rispetto a un'unione a 2 vie e spesso a volte non è necessario l'intervento dell'utente. Perché è così?

Un esempio in cui una fusione a 3 vie ha esito positivo e una fusione a 2 vie fallisce sarebbe utile.

Risposte:


259

Di 'che tu e il tuo amico avete estratto un file e apportato alcune modifiche. Hai rimosso una riga all'inizio e il tuo amico ha aggiunto una riga alla fine. Quindi ha eseguito il commit del suo file e devi unire le sue modifiche nella tua copia.

Se stavi facendo un'unione a due vie (in altre parole, una diff), lo strumento potrebbe confrontare i due file e vedere che la prima e l'ultima riga sono diverse. Ma come farebbe a sapere cosa fare con le differenze? La versione unita dovrebbe includere la prima riga? Dovrebbe includere l'ultima riga?

Con un'unione a tre vie, può confrontare i due file, ma può anche confrontare ciascuno di essi con la copia originale (prima che uno di voi lo abbia cambiato). Quindi può vedere che hai rimosso la prima riga e che il tuo amico ha aggiunto l'ultima riga. E può usare queste informazioni per produrre la versione unita.


"Ma come farebbe a sapere cosa fare delle differenze?" Non l'ho capito. Se riesce già a vedere le differenze tra i due file (senza riferimento all'originale), perché non può applicare entrambe le modifiche in serie in ordine crescente di timestamp dei file? Cioè: inizia con la copia impegnata del mio amico assumendolo come (nuovo) originale (con l'aggiunta della riga in alto) e quindi, in cima ad esso, applica le mie modifiche locali (eliminazione della riga in basso).
Harry,

7
@Harry Dire che l'originale aveva tre righe (ABC). Inizia con la copia del mio amico (ABCD) e la confronta con la mia (BC). Senza vedere l'originale, potrebbe pensare che ho rimosso sia A che D, e che il risultato finale dovrebbe essere BC.
JW.

80

Questa diapositiva da una presentazione perforce è interessante:

immagine diapositiva

La logica essenziale di uno strumento di unione a tre vie è semplice:

  • Confronta i file di base, di origine e di destinazione
  • Identificare i "blocchi" nel file di origine e file di destinazione:
    • Pezzi che non corrispondono alla base
    • Pezzi che corrispondono alla base
  • Quindi, componi un risultato unito costituito da:
    • I pezzi che corrispondono l'un l'altro in tutti e 3 i file
    • I blocchi che non corrispondono alla base né nella sorgente né nella destinazione ma non in entrambi
    • I pezzi che non corrispondono alla base ma che corrispondono l'un l'altro (cioè sono stati cambiati allo stesso modo sia nella sorgente che nella destinazione)
    • Segnaposto per i blocchi in conflitto, che devono essere risolti dall'utente.

Si noti che i "pezzi" in questa illustrazione sono puramente simbolici. Ciascuno potrebbe rappresentare linee in un file, o nodi in una gerarchia, o persino file in una directory. Tutto dipende da cosa è capace un particolare strumento di unione.

Potresti chiedere quale vantaggio offre un'unione a 3 vie rispetto a un'unione a 2 vie. In realtà, non esiste una fusione bidirezionale, ma solo strumenti che diffondono due file e ti permettono di "unire" selezionando blocchi da un file o dall'altro.
Solo un'unione a 3 vie ti dà la possibilità di sapere se un pezzo è o meno un cambiamento rispetto all'origine e se i cambiamenti cambiano o meno.


"se cambia il conflitto o meno". - L'unione a 2 vie (diff) non mostra un conflitto (anche se le informazioni vengono perse a partire dalla fonte del conflitto) /
Vlad

1
È comunque comune in Git avere una fusione a 4 vie in cui la base non è effettivamente la stessa. Ancora una fusione a 3 vie è migliore e a 2 vie.
Wernight,

@Wernight, c'è una fusione a 5 vie?
Pacerier,

@Pacerier Non che io sappia, ma è quello che sta realmente succedendo durante un git cherry-pick, o rebase.
Wernight,

Spiegazione molto dettagliata e utile
Kaneg,

20

Ho scritto un post molto dettagliato al riguardo . Fondamentalmente non è possibile tenere traccia delle eliminazioni / aggiunte con due vie, molto, molto improduttivo.


@pablo, se aggiungo una funzione prima di X e aggiungi un'altra funzione dopo X e facciamo un'unione a tre vie, lo strumento applicherebbe automaticamente entrambe le modifiche. Ma cosa succede quando la mia modifica è effettivamente in conflitto con la tua modifica (ad esempio, ognuno di noi crea una nuova funzione con lo stesso nome di funzione)? In che modo si suppone che la fusione automatica sappia che una parte della nostra unione "noiosamente facile" può effettivamente causare un conflitto ?
Pacerier,

1
Leggi il tuo tutorial ed è davvero utile per me. Mi sento allo stesso modo degli sviluppatori che hai descritto. Ho sempre temuto la fusione a tre vie.
racl101,

3
Ti suggerirei di copiare e incollare parti del tuo articolo. Penso che questo ti aiuterà a ottenere voti positivi e sarà più allineato con la filosofia di StackOverflow.
Samuel,

Buon articolo Mi piaceva usare le patch per rebase mentre vedi più contesto e puoi usare il tuo editor e ambiente per controllare le cose, però c'è troppo munging manuale di cose facili in quel modo. È un peccato che non ci sia un modo carino di combinare le parti buone di entrambi
JonnyRaa

20

Un'unione a tre vie in cui due gruppi di modifiche in un file di base vengono uniti man mano che vengono applicati, anziché applicarne uno, quindi unendo il risultato con l'altro.

Ad esempio, avere due modifiche in cui una linea viene aggiunta nello stesso posto potrebbe essere interpretata come due aggiunte, non una modifica di una riga.

Per esempio

il file a è stato modificato da due persone, una che aggiunge alci e una che aggiunge il mouse.

#File a
    dog
    cat

#diff b, a
    dog
+++ mouse
    cat

#diff c, a
    dog
+++ moose
    cat

Ora, se uniamo i changeset mentre li applichiamo, otterremo (unione a 3 vie)

#diff b and c, a
    dog
+++ mouse
+++ moose
    cat

Ma se applichiamo b, allora osserviamo il cambiamento da b a c sembrerà che stiamo solo cambiando un 'u' in un 'o' (unione a 2 vie)

    #diff b, c
    dog
--- mouse
+++ moose
    cat
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.