2010-11-08 15 views

risposta

154

di 'tu e il tuo amico sia estratto un file e ha apportato alcune modifiche ad esso. Hai rimosso una linea all'inizio e il tuo amico ha aggiunto una linea alla fine. Quindi ha eseguito il commit del file e è necessario unire le modifiche nella copia.

Se si stesse eseguendo 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, è possibile confrontare i due file, ma può anche confrontare ciascuno di essi con la copia originale (prima di averlo modificato). Quindi può vedere che hai rimosso la prima riga e che il tuo amico ha aggiunto l'ultima riga. E può usare quelle informazioni per produrre la versione unita.

+0

durante la sincronizzazione con il repository remoto in eclissi, ho ottenuto una serie di righe nel codice remoto ottenute confrontate con una singola riga vuota nel codice locale e quindi in conflitto. Ma quelle linee erano presenti anche nel mio codice locale. Non so perché il plug-in di eclipse lo stesse confrontando con una singola riga vuota. In effetti c'erano molte di queste istanze in molti file. Sono tornato al confronto a due vie e tutto inizia a sembrare corretto. In precedenza non ho mai provato un confronto a due vie. Sto indovinando se dovrei mantenere la modalità di confronto bidirezionale ON per impostazione predefinita, perché io comunque attraverso il codice durante la risoluzione dei conflitti e l'esecuzione di unire .. – Mahesha999

11

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

Ad esempio, avere due modifiche in cui una riga viene aggiunta nello stesso luogo potrebbe essere interpretata come due aggiunte, non un cambiamento di una riga.

Per esempio

un file è stato modificato da due persone, un'alce aggiunta, una aggiunta di mouse.

#File a 
    dog 
    cat 

#diff b, a 
    dog 
+++ mouse 
    cat 

#diff c, a 
    dog 
+++ moose 
    cat 

Ora, se noi fondiamo i gruppi di modifiche come noi li applichiamo, avremo (3-way merge)

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

Ma se applichiamo b, poi guardare il passaggio da B a C sarà simile ci sono solo cambiando una 'u' ad una 'O' (2-way merge)

#diff b, c 
    dog 
--- mouse 
+++ moose 
    cat 
47

This slide da una presentazione per forza è interessante:

alt text

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

  • Confronta base, sorgente e file di destinazione
  • Identificare i "blocchi" nel file dei file di origine e di destinazione:
    • Pezzi che non corrispondono alla base
    • Pezzi che fanno corrispondere la base
  • Poi, messo insieme un risultato unito composto da:
    • I pezzi che corrispondono l'un l'altro in tutte le 3 file
    • I blocchi che non corrispondono alla base nella sorgente o nel target ma non in entrambi
    • I blocchi che non corrispondono alla base ma che corrispondono a ciascuno lei (cioè, sono stati cambiati allo stesso modo sia nella fonte che nell'obiettivo)
    • Segnaposti per i blocchi che sono in conflitto, da risolvere dall'utente.

Nota che i "pezzi" in questa illustrazione sono puramente simbolico. Ciascuno può rappresentare linee in un file o nodi in una gerarchia o anche file in una directory. Dipende tutto da cosa è capace un particolare strumento di unione.

Forse starai chiedendo quale vantaggio un unione a 3 vie offre su un'unione a 2 vie. In realtà, non esiste un'unione a due vie, solo strumenti che diff due file e consentono di "unire" scegliendo i pezzi da un file o l'altro.
Solo un'unione a 3 vie consente di sapere se un blocco è o meno una modifica dall'origine e se le modifiche cambiano o meno.

+0

"anche se non cambia conflitto." - l'unione non bidirezionale (diff) mostra anche un conflitto (anche se le informazioni vengono perse a partire dalla fonte del conflitto)/ – Vlad

+1

È tuttavia comune in Git avere un'unione a 4 vie in cui la base non è in realtà lo stesso. Ancora una fusione a 3 vie è migliore e a 2 vie. – Wernight

+0

@Wernight, Esiste un'unione a 5 direzioni? – Pacerier

14

Ho scritto un very detailed post about it. Fondamentalmente non è possibile tracciare cancella/aggiungi con a doppio senso, molto, molto improduttivo.

+0

@pablo, Se aggiungo una funzione prima di X e aggiungete un'altra funzione dopo X e facciamo un'unione a tre vie, lo strumento dovrebbe ** automaticamente ** applicare entrambe le modifiche. Ma cosa succede quando la mia modifica in realtà è in conflitto con la tua modifica (ad esempio, ognuno di noi crea una nuova funzione con lo stesso nome di funzione)? In che modo la fusione automatica dovrebbe sapere che una nostra unione "noiosamente semplice" può effettivamente causare un conflitto **? – Pacerier

+1

Basta leggere il tuo tutorial ed è molto utile per me. Mi sento allo stesso modo degli sviluppatori che hai descritto. Ho sempre temuto la fusione a tre. – racl101

+0

Ti suggerisco di copiare e incollare parti del tuo articolo. Penso che questo ti aiuterà a guadagnare voti e sarà più allineato con la filosofia dello stackoverflow. – Samuel