E 'ormai generalmente hanno concordato che l'algoritmo di fusione a 3 vie (magari con miglioramenti quali come il rilevamento di rinomina e trattare con la storia più complicata), che prende in versione considerazione sul ramo corrente ('la nostra'), versione on il ramo unito ("loro") e la versione di antenato comune dei rami uniti ("antenato") è (dal punto di vista pratico) il modo migliore per risolvere le unioni. Nella maggior parte dei casi, e per la maggior parte dei contenuti, il livello dell'albero si fonde (quale versione del file da prendere) è sufficiente; raramente c'è bisogno di gestire i conflitti dei contenuti, e quindi l'algoritmo diff3 è abbastanza buono.
Per utilizzare l'unione a 3 vie è necessario conoscere l'antenato comune dei rami uniti (co denominato base di unione). Per questo è necessario conoscere la cronologia completa tra quelle filiali. Ciò che mancava a Subversion prima (corrente) versione 1.5 (senza strumenti di terze parti come SVK o svnmerge) era tracciamento unione, vale a dire ricordare per l'unione di commit quali genitori (quali commit) sono stati utilizzati in unione. Senza questa informazione non è possibile calcolare correttamente l'antenato comune in presenza di fusioni ripetute.
Prendere per conto schema seguente:
---.---a---.---b---d---.---1
\ /
\-.---c/------.---2
(che sarebbe probabilmente ottenere straziati ... sarebbe bello avere la capacità di disegnare diagrammi ASCII-art qui).
Quando stavamo unendo i commit 'b' e 'c' (creando commit 'd'), l'antenato comune era il punto di ramificazione, commit 'a'. Ma quando vogliamo unire i commit '1' e '2', ora l'antenato comune è commit 'c'. Senza memorizzare le informazioni di fusione, dovremmo concludere erroneamente che è commit 'a'.
Subversion (precedente alla versione 1.5) e CVS precedente hanno reso difficile l'unione perché era necessario calcolare personalmente un antenato comune e fornire manualmente informazioni sull'antenato quando si esegue un'unione.
Git memorizza le informazioni su tutti i genitori di un commit (più di un genitore nel caso di un merge di commit) nell'oggetto commit. In questo modo puoi dire che Git memorizza DAG (grafico aciclico diretto) delle revisioni, memorizzando e ricordando le relazioni tra i commit.
(io non sono sicuro di come offerte di Subversion con le questioni di cui qui di seguito)
Inoltre si fondono in Git possono affrontare due questioni complicazione: file di rinomina (quando una parte rinominato un file e altro no, vogliamo ottenere il cambio di nome e vogliamo applicare le modifiche al file corretto) e si fonde in modo incrociato (cronologia più complessa, quando esiste più di un antenato comune).
- File rinomina durante l'unione sono gestiti con il punteggio di somiglianza euristica base (sia similarità dei contenuti di file e somiglianza del percorso viene presa in considerazione) rename rilevamento. Git rileva quali file corrispondono tra loro in rami uniti (e antenati). In pratica funziona abbastanza bene per casi reali.
- Criss-cross fonde, vedere definition at revctrl.org wiki, (e presenza di più basi unione) sono gestiti utilizzando ricorsiva strategia unione, che genera singolo antenato comune virtuale.
In risposta a: "SVN ha reso la ramificazione molto più semplice rendendo i rami davvero economici". Sei sicuro di non aver accidentalmente sostituito Git con SVN? So che una delle grandi funzionalità che Git vanta è la ramificazione economica ... Ho sentito dire che la ramificazione in SVN è un incubo perché gran parte di essa è manuale (crea una nuova directory con contenuti ramificati, ecc.). – Stunner