2009-11-05 15 views
18

Se si sincronizza sempre un ramo di funzione prima di unirlo nuovamente. Perché devi davvero usare l'opzione --reintegrate?Quando è veramente necessaria l'opzione di reintegrazione?

Il Subversion libro dice:

Quando si uniscono il vostro ramo di nuovo al tronco, però, la matematica di base è molto diversa. Il tuo ramo di funzionalità è ora una mistura di entrambe le modifiche di tronco duplicate e le modifiche di ramo privato, quindi non c'è una semplice gamma contigua di revisioni da copiare. Specificando l'opzione --reintegrate, stai chiedendo a Subversion di replicare accuratamente solo le modifiche univoche al tuo ramo. (E infatti, lo fa confrontando il tronco più recente con l'ultimo ramo di albero: la differenza risultante è esattamente vostre modifiche del ramo!)

Quindi l'opzione --reintegrate unisce solo le modifiche che sono unici per la funzione ramo. Ma se si sincronizza sempre prima di unire (che è una pratica consigliata, al fine di gestire eventuali conflitti sul ramo di funzionalità), le uniche modifiche tra i rami sono le modifiche univoche al ramo di funzione, giusto? E se Subversion cerca di unire il codice che è già sul ramo di destinazione, non farà nulla, giusto?

In a blog post, Mark Phippard scrive:

Se includiamo quelle revisioni sincronizzate, poi uniamo indietro cambiamenti che già esistono in tronco. Ciò genera conflitti inutili e confusi.

C'è un esempio di quando il reinserimento reintegrato mi dà conflitti inutili?

risposta

10

Lasciatemi spiegare quando è assolutamente necessario --reintegrate.

Considerare il seguente caso d'uso.

  1. voi hanno progetto p1 sotto P1/tronco. Il progetto dispone di un file, readme.txt, con una linea "linea 1" <
  2. Creare un nuovo ramo, P1/rami/BR1
  3. Soggiorno in tronco. Aggiungere la riga "riga2" a readme.txt e vincolarla al trunk
  4. Passare al ramo p1/branches/br1. Aggiorna a HEAD.
  5. Unisci dal tronco a questo ramo (per raccogliere le variazioni del tronco).
  6. Si dovrebbe avere line1 e line2 in readme.txt
  7. Commit unire il risultato p1/branches/br1 ramo
  8. Passa a tronco. Aggiorna a HEAD.
  9. Merge from p1/branches/br1 to trunk.
    1. Vedrai line1, line2 e line2 in readme.txt. Quindi, hai "line2" due volte che non è corretto. SVN non mostra alcun conflitto. Quindi, è molto pericoloso perché l'unione viene eseguita senza errori e si ha l'impressione che tutto vada bene.

La soluzione è che l'unione passaggio 9 dovrebbe essere fatto utilizzando l'opzione --reintegrate. L'opzione reintegrare indica a SVN di confrontare br1 con il trunk e di applicare solo le modifiche br1 al trunk. In questo caso particolare non abbiamo apportato alcuna modifica in br1. Il risultato nel trunk dovrebbe essere due linee "line1" e "line2".

Un'altra osservazione utile. Il ramo p1/branches/br1 non dovrebbe più essere utilizzato per lo sviluppo dopo il passaggio 9. Se si desidera continuare lo sviluppo nelle filiali, creare un nuovo ramo, ad esempio p1/branches/br2. Un'altra unione dal trunk a p1/branches/br1 causa molti conflitti.

+2

Ho appena eseguito questo test utilizzando SVN 1.7.0 e non vedo che ciò accada. Quello che vedo invece è SVN che filtra automaticamente i changeset che esistono già nei rami correlati indipendentemente dalla direzione della fusione (da linea a linea o da linea a linea). Il comportamento di SVN in quest'area è cambiato in un modo che non si riflette nella documentazione? – Neutrino

+2

Ho anche eseguito il test con Netbeans 7.3.1 (che dovrebbe utilizzare SVN 1.7), il mio server SVN è 1.6.17 e non ho alcun problema con le righe duplicate. – betatester07

0

Penso che Mark significhi evitare di confrontare due file che sono stati modificati, uno da reintegrare dal ramo e il suo file corrispondente nel trunk, quando entrambi sono stati sincronizzati (e non solo modificati localmente nel rispettivo ramo).

Supponiamo di avere trunk/a.c e branches/dev/a.c, con trunk/a.c modificato a un certo punto e reintegrato nel ramo in seguito con un'unione. Come hai sottolineato, è una buona pratica farlo prima di rimettere tutto nel bagagliaio.

Quindi il passaggio successivo sarebbe quello di unire nuovamente il tronco, dove a.c sono "diversi" da entrambi i lati poiché sono stati modificati in entrambe le posizioni. Senza l'opzione ci sarà un confronto non necessario, in cui il --reintegrate farà sì che SVN veda che la modifica non era solo locale.

+2

Sì, posso capire il "confronto non necessario". Ma non il "conflitto non necessario", di cui parla la documentazione. –

0

E ’ s mai necessario utilizzare --reintegrate — it ’ s semplicemente un alias. Se si dispone di una copia di lavoro di trunk, poi

svn merge --reintegrate url://feature-branch workingcopy

è lo stesso di

svn merge url://trunk url://feature-branch workingcopy

È possibile utilizzare qualunque uno sei più a suo agio con.

+0

Hmm. Non sono sicuro al 100%, ma penso che ti sbagli su questo. Almeno lo svnbook dà un'immagine abbastanza diversa di esso. http://svnbook.red-bean.com/nightly/en/svn.branchmerge.basicmerging.html#svn.branchemerge.basicmerging.stayinsync – Jonik

+0

@ Michael: Ne sei veramente sicuro? Nella documentazione SVN è abbastanza chiaro il comportamento è diverso, vuoi dire che rileva automaticamente dalla specifica dei due URL? – RedGlyph

+3

Questo dipende dal collegamento specificato nell'OP. "La nuova opzione di reintegrazione è una versione abbreviata della fusione di 2 URL ... In altre parole, il reinserimento è solo una nuova sintassi più alcuni controlli di sicurezza." Mi scuso, ma non ho esperienza diretta con questa opzione . –

3

Non è mai necessario utilizzare --reintegrate; è una comodità.Se la fusione più recente da trunk a feature-branch ha unito tutte le modifiche che si sono verificate in trunk poiché si è ramificata alla revisione rev, è possibile utilizzare il seguente comando.

svn merge url://[email protected] url://feature-branch . 

Nota che questo comando sarebbe stato eseguito in radice di una copia up-to-date di lavorare trunk senza modifiche in sospeso da impegnare.

Lasciatemi espandere la mia risposta per rispondere più direttamente alla domanda "C'è un esempio di quando il reintegro del reinserimento mi dà conflitti inutili?"

Ecco cosa significa l'articolo "Se includiamo quelle revisioni sincronizzate, quindi uniamo le modifiche che già esistono nel trunk. Ciò genera conflitti non necessari e confusi."

Comprese le revisioni sincronizzate sarebbe simile a questa:

svn merge -r N:HEAD url://feature-branch . 

Dove . è una copia di lavoro pulito del tronco e N è la revisione che feature-branch è stato creato da trunk. Il comando di unione unisce tutte le modifiche apportate allo feature-branch poiché era ramificato, comprese le modifiche che erano state unite da trunk dopo la creazione dello feature-branch. Ciò significa che le modifiche già apportate a trunk verranno incluse nell'unione sopra. Comuniceresti a Subversion di applicare le modifiche a trunk effettivamente originate in trunk, che genera conflitti.

+0

Beh, questo è quello che non capisco. Perché le modifiche esistenti nel ramo e nel tronco portano a conflitti, se tali cambiamenti sono identici? –

+2

@Tor, vedresti un conflitto se hai apportato modifiche al ramo al codice modificato. In altre parole, tali modifiche potrebbero non essere più identiche. Immagina di aver aggiunto 5 linee sul tronco, sincronizzate con il ramo e quindi modificate sul ramo. Un'unione mostrerebbe quindi un conflitto: 5 linee sul tronco rispetto a 5 linee diverse sul ramo. Ma se hai usato --reintegrate, noterebbe semplicemente la differenza sul ramo e lo unisci senza chiedere conferma. –

+0

Significa che durante l'unione senza reintegrazione, dì "svn merge -r 1: 100 url: // feature-branch." troverà tutte le modifiche apportate a url: // feature-branch da rev 1 a rev 100 e le applicherà a ognuna di esse. uno per uno. Mentre con reintegrazione, SVN confronterà semplicemente la differenza tra rev 100 e rev 1 e tratterà queste differenze come modifiche, quindi si applicherà a. ? – CarmeloS

Problemi correlati