Italiano - English

Appunti SVN (subversion)

In queste pagine vengono raccolte i miei appunti sul contollo delle versioni del software utilizzando subversion

Appunti SVN

SVN (SubVersion) è quasi il successore di CVS (Concurrent Version System). Dico quasi perché non è semplicemente la sua evoluzione ma la sua “industrializzazione”. Il sistema CVS risale agli anni 80 ed è un progetto open source nato da Dick Grune seguito da molti altri. Il sistema SVN nasce nel 2000 da CollabNet che intende riscrivere completamente CVS perché “wasn't implemented as well as it could be”. CollabNet, consapevole della diffusione di CVS ha intrapreso una semplice strategia, riscrivere CVS con tutte le sue funzionalità, in modalità opensource cercando di attrarre gli sviluppatori di CVS al nuovo progetto e cercando di risolvere quelli che ne ritenevano i difetti. Il risultato oggi è un prodotto opensource con qualche funzione differente e un fratello maggiore enterprise a pagamento. Nel frattempo il progetto CVS ha perso sostenitori e ad oggi è dato per non attivo (anche se ancora fortemente diffuso)

Questo scenario sta spingendo utenti come sourceforge alla migrazione da CVS a SVN.

Allo stato attuale ci sono criticismi a riguardo , SVN è concettualmente differente da CVS al punto da non poter essere considerato una sua evoluzione ma un differente prodotto come ad esempio tra C e Java. Alcune scelte fatte dagli sviluppatori di SVN non sono ampiamente condivise dagli utenti di CVS (così come i puntatori in java mancano ai programmatori C). A tale proposito ci sono numerosi link tra cui ho trovato interessanti

Al momento in cui scrivo non sono un esperto di version control e non sono in grado di apprezzare a fondo le differenze, tuttavia l’impressione e’ che SVN sia piu’ semplice e portabile. La mia scelta finale verso SVN è comunque fortemente condizionata dal fatto che CVS è in declino mentre SVN è supportato.

Cosa è SVN ?

SVN (o subversion) è un version control system open source. Ovvero è un sistema che permette di tenere traccia dei cambiamenti nel tempo di un file system. Questa è la differenza concettuale e sostanziale con CVS. CVS è orientato al codice sorgente mentre SVN è orientato a file e directory. La logica di CVS è quella di gestire differenze tra diverse versioni di file di testo, e benché sia in grado di gestire file anche binari ad esempio è lacunoso riguardo alle directory. Al contrario SVN funziona come un vero file sharing a cui è aggiunta la funzionalità di traccia nel tempo. A parità di risultato un archivio SVN è decisamente più grande di uno CVS proprio perché il primo conserva l’intero file mentre il secondo solo le differenze.

 In SVN esiste

  • Repository: è l’archivio delle revisioni di un progetto sul server gestito da SVN
  • Working copy: è un albero di directory ordinario di un progetto, sul tuo disco locale.

Gestione della concorrenza.

La modifica temporanea da parte di diversi utenti verso uno stesso file viene gestita con la logica copy-modify-merge, a differenza di quando accade nel file sharing in cui viene utilizzata la logica lock-modify-unlock. La logica prevede un merge semiautomatico delle differenze, ovvero il secondo che salva il file in archivio riceve un messaggio di conflitto con indicazione delle differenze tra la copia locale e quella in archivio. A questo punto l’utente verifica le differenze, risolve il conflitto quindi salva la versione unificata in archivio.

Questa logica funziona bene con il testo ma ad esempio in caso di file audio o video porta sicuramente a perdite di tempo. Infatti non e’ sempre possibile unificare due modifiche fatte ad una foto. In questi casi la logica lock-modify-unlock serializza il lavoro degli utenti e funziona meglio. SVN fornisce un meccanismo LMU

Repository

Il Repository è l’archivio delle revisioni di un progetto. Il repository e’ gestito da SVN in una cartella. Normalmente ogni progetto ha un suo repository ovvero una cartella e contiene tutti i file di gestione di quel progetto. Quindi parlo indifferentemente di progetto o cartella o di repository.

Dato che SVN gestisce il progetto come un vero file system, il repository avrà una struttura di cartelle identica a quella definita per il progetto, al momento della sua importazione in SVN.

 

La struttura che finisce nel repository sarà quella definita al momento dell’oprerazione di import. La struttura delle cartelle di un progetto è variabile tuttavia è fortemente consigliato di organizzare il progetto a partire da 3 sottocartelle cartelle, ovvero:

MioProgetto (cartella principale di un progetto)

trunk (tronco): contiene la linea di sviluppo principale

branches (rami): contiene le eventuali versioni derivate

tags (etichette): contiene le fotografie di un progetto ad un dato istante, spesso associate ad una versione di rilascio.

 

Ad ogni commit il numero di revisione di MioProgetto viene incrementato indipendentemente che riguardi file contenuti in trunk/branches/tags. In caso di progetti complessi, composti da diversi sottoprogetti si può organizzare la struttura in due modi differenti.

Organizzazione per rami

Organizzazione per progetto

  • MioProgetto
    • Trunk
      • SottoProgetto1
      • SottoProgetto2
    • Branches
      • SottoProgetto1
      • SottoProgetto2
    • Tags
      • SottoProgetto1
      • SottoProgetto2
  • MioProgetto
    • SottoProgetto1
      • Trunk
      • Branches
      • Tags
    • SottoProgetto2
      • Trunk
      • Branches
      • Tags

La scelta è libera e dovrebbe essere fatta in funzione di quanto i sottoprogetti sono collegati. L’organizzazione a progetto ha senso quando i sottoprogetti non sono strettamente connessi tra loro, ognuno può essere distribuito singolarmente ecc…

La scelta implica che le operazioni di committ,chekout e update vengono eseguite su tutti i rami di un progetto o su tutti i progetti di un ramo. Quindi, ad esempio, se si vuole avere un numero di versione (tag) unico per tutti i sottoprogetti allora è bene scegliere l’organizzazione a rami. Se ogni progetto ha vita propria ma comunque è parte di un progetto principale allora è bene scegliere l’organizzazione a progetto.

Nel caso il repository venga creato a priori con l’operazione di create, è possibile creare la struttura di directory desiderata con gli appositi comandi SVN.

URL

Un repository è raggiungibile tramite un protocollo di rete. URL è l’indirizzo di un repository completo di protocollo e indirizzo del server. URL segue questo schema:

 

file://[localhost]/

Accesso diretto sul disco locale. Su windows può contenere anche il disco nella forma

File:///Z:/Programmi/ecc... (nota le slash)

http:///

Accesso via Apache/WebDAV sul sito

https:///

Come sopra con encript SSL

svn:///

Accesso via protocollo svn ad un server svn sulla macchina

svn+ssh:///

Come sopra ma con tunnell SSH

Working copy

E’ una cartella (con eventuali sottocartelle) ordinaria sul tuo disco locale. Di fatto e’ la copia di lavoro su cui l’utente può fare qualsiasi cosa. L’utente puo però pubblicare sul repository le modifiche fatte in locale e/o aggiornare la sua copia locale con le modifiche fatte altri

Una copia locale aggiornata, contiene almeno tutti i file del progetto, eventuali altri file generati dall’utente e una cartella di amministrazione del progetto chiamata .svn . Il contenuto di questa cartella serve ad SVN per la gestione degli aggiornamenti.

Creare una working copy (chekout)

Riceve una copia completa del progetto specifico

Aggiornare il repository (commit)

Aggiorna il repository con le modifiche effettuate sulla copia locale

Aggiornare la working copy (update)

Aggiorna la copia locale con l’ultima versione presente sul repository

Revisioni

Un commit aggiorna il repository con le modifiche effettuate sulla copia locale. Questa operazione genera delle revisioni del progetto. Una revisione di un progetto è un nuovo stato del repository. Una revisione è indicata con un numero progressivo 0..N. Ad ogni commit viene creato un nuovo stato del repository ed incrementato il numero di revisione. Il numero di revisione quindi è associato allo stato dell’intero progetto e non del singolo file (come accade con CVS), anche se si modifica un solo file al momento del commit viene creata una nuova revisione per l’intero progetto.

Working copy verso Repository

Considerato che le operazioni di commit vengono normalmente svolte da utenti differenti la propria working copy può avere uno stato (revision) differente da quelle presente sul repository. Differente perche’ a sua volta l’utente può aver modificato un file dopo l’ultimo update. In generale ci sono 4 possibili stati (status)

  1. Nessun file e’ stato modificato sia nella working copy che nel repository. Il sistema e’ sincronizzato e operazioni di commit o update non hanno effetto
  2. Nessuna modifica al repository ma uno o piu’ file locale e’ cambiato. La copia locale contiene file che devono essere posti nel repository. Una operazione di commit porta il sistema allo stato sincronizzato. Una operazione di update non ha effetto
  3. Nessuna modifica locale ma il repository e’ stato aggiornato. La copia locale contiene file vecchi che devono essere aggiornati con un update. Una operazione di commit non ha effetto.
  4. Sia il repository che la copia locale contengono file modificati. Il sistema e’ uno stato di conflitto. E’ necessario eseguire prima una operazione di update che cerca di unire la versione aggiornata presente sul repository con quella aggiornata presente sulla copia locale. Se SVN può unificare le due versioni in modo automatico, si può eseguire poi un commit, altrimenti l’utente deve prima risolvere il conflitto manualmente.

Spostare, Copiare, Cancellare un repository

Queste operazioni possono essere fatte utilizzando i comandi del sistema operativo. Un repository infatti è una normale cartella pertanto puo’ essere manipolata normalmente. Naturalmente tali “manipolazioni” richiedono di impostare il server SVN in modo da puntare alla nuova cartella. Anche il client deve puntare al nuovo URL che sarà conseguenza delle modifiche al repository.

NOTA: Ogni repository ha un proprio ID. In caso di copia di un repository, si copia anche l’ID (visto che e’ indicato in un file). Tale circostanza non è un problema ma nel caso fosse necessario generare un nuovo ID per la copia vedi le istruzioni relative nel SVN Book

Ignorare files da SVN

Per fare in modo che SVN ignori automaticamente dei file è necessario modificare di configurazione globale di SVN. Il file in questione, su windows, è

C:\Document and Settings\\Application Data\Subversion\config

Nella sezione [miscellany] modificare global-ignores = elenco dei file da ignorare separate da spazio... ad esempio:

global-ignores = *.exe *.dcu *.obj *.~* *.*~ *.local *.identcache *.bak *.tmp *.del *.off *.map *.log *.o *.lo *.la *.al *.libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store Thumbs.db

Sono validi i caratteri jolli *=zero o piu’ caratteri; ? = un carattere; [] uno o tutti i caratteri inclusi nelle parentesi.

Keywords

Le keyword sono proprietà predefinite in SVN e sono parole chiave che vengono sostituite nel file al momento del suo commit. E’ possibile impostare proprietà personalizzate dal contenuto qualsiasi, tuttavia le parole chiave predefinite e gestite automaticamente sono

  • $Date$: data dell’ultimo commit
  • $Author$: dell’ultimo commit
  • $Rev$: Ultimo numero di revisione
  • $Id$: Insieme dei precedenti valori in forma abbreviata
  • $URL$: la URL completa del file nel repository

Le keyword sono normalmente disattivate, questo vuol dire che la sostituzione non avviene se non richiesto espressamente quindi attivando le keyword.

Per attivare le keyword è necessario operare sulla copia locale

Utilizzare la linea di comand svn ad esempio:

c:\> svn propset svn:keywords "Date Author" prova.c 

attiva le keyword Date e Author sul file prova.c (sono validi I caratteri jolli)

Utilizzare TortoiseSVN:


Aprire il browser ->Tasto destro sul/sui file interessato/I ->TortoiseSVN->Properties …Si apre la maschera delle proprietà a cui e’ necessario aggiungere le proprietà volute.

Keyword Automatiche

Per attivare le keyword in modo automatico, è necessario modificare il file di configurazione globale di SVN. Il file in questione, su windows, è

C:\Document and Settings\\Application Data\Subversion\config

 Nota: le keyword automatiche hanno effetto solo sui nuovi file, quindi sugli import effettuati dopo la modifica alla configurazione

 Nella sezione [miscellany] modificare enable-auto-props = yes e nella sezione [auto-props] aggiungere righe per ogni tipo di file su cui si vuole attivare le keyword. Ad esempio per i file .pas

*.pas = svn:eol-style=native;svn:keywords = Date Author Rev Id

Proprietà Personalizzate

E’ possibile definire delle proprietà personalizzate associate ad uno o più file, ad esempio:

c:\>svn propset copyright "(c) 2009 PkLab.net" main.pas

definisce la proprietà copyright per il file main.pas e la imposta al valore  “(c) 2009 PkLab.net”

Una modalità piu’ comoda e’ la seguente

c:\>svn propset license -F /path/to/LICENSE main.pas

In questo esempio viene definita la proprietà license per il file main.pas e il valore della proprietà viene letta dal file /path/to/LICENSE. In questo modo si evita di scrivere il testo completo oppure si può  impostare un valore binario come ad esempio un file .jpg.

E’ possibile utilizzare i caratteri jolli per impostare la stessa proprietà a piu’ files contemporaneamente. Ad esempio:

c:\>svn propset license -F /path/to/LICENSE *.pas

Al momento le proprietà non possono essere "esplose" nel file come accade per le keyword ma rimangono informazioni aggiuntive collegate al file

Vendor Branch

Un progetto EdgeDetection fa uso di una libreria per la trasformata di hugh chiamata hughlib-1.0, e di una libreria per la fast fourier transform chiamata fftlib-2.1. La Struttura delle cartelle del progetto è la seguente

	/
  /src
    /hughlib
    /fftlib
    
  /bin
    

Il progetto ha un suo repository all'indirizzo file:///Z:/SVN/EdgeDetection/ con la classica  struttura trunk/braches/tags

Nella radice del repository, sarà creata una cartella per contentere tutte le librerie di terze parti della applicazione ovvero tutti i vendor branches. Ad esempio /vendor. Così il repository avrà la struttura trunk/braches/tags/vendor

  • Importare le distribuzioni delle librerie in una subdirectory di quella di cui sopra; (nell'esempio le distribuzioni delle librerie sono nella cartella c:\dist)
	c:\> svn import c:\dist\hughlib-1.0 \
     file:///Z:/SVN/EdgeDetection/vendor/hughlib/current \
     -m 'import iniziale alla versione 1.0'

c:\> svn import c:\dist\fftlib-2.1 \
     file:///Z:/SVN/EdgeDetection/vendor/fftlib/current \
     -m 'import iniziale alla versione 2.1'

La cartella vendor viene creata automaticamente nel repository al momento dell'import. Ora è disponibile la versione attuale delle librerie nelle rispettive cartelle current.

  • Creare un tag per la versione attuale delle librerie:
	c:\> svn copy file:///Z:/SVN/EdgeDetection/vendor/hughlib/current \
              file:///Z:/SVN/EdgeDetection/vendor/hughlib/1.0 \
              -m 'conservo la versione 1.0 di hughlib'

c:\> svn copy file:///Z:/SVN/EdgeDetection/vendor/fftlib/current \
              file:///Z:/SVN/EdgeDetection/vendor/fftlib/2.1 \
              -m 'conservo la versione 2.1 di fftlib'
  • Inserire le librerie della versione attualmente utilizzata, nel tronco principale del progetto, alla posizione desiderata, in questo caso ./src:
c:\> svn copy file:///Z:/SVN/EdgeDetection/vendor/hughlib/1.0 \
              file:///Z:/SVN/EdgeDetection/trunk/src/hughlib \
              -m 'Inserisco hughlib-1.0 nel tronco del progetto'
c:\> svn copy file:///Z:/SVN/EdgeDetection/vendor/fftlib/2.1 \
              file:///Z:/SVN/EdgeDetection/trunk/src/fftlib \
              -m 'Inserisco fftlib-2.1 nel tronco del progetto'

Ora un chekout del progetto crea la working copy e include le due librerie nella posizione desiderata. Ad esempio se si vuole la working copy in c:\progetti\EdgeDetection:

c:\>cd progetti
c:\progetti>svn checkout file:///Z:/SVN/EdgeDetection/trunk/ EdgeDetection

a questo punto la cartella c:\progetti\EdgeDetection avrà la struttura come descritto all'inizio di questo paragrafo. Le due cartelle delle librerie conterranno una copia delle versioni 1.0 e 2.1 rispettivamente.

Lo sviluppo dell'applicazione può procedere e molto probabilmente è necessario apportare qualche personalizzazione ai file sorgenti di una o entrambe le librerie. Le conseguenti operazioni di committ avranno influenza solo nell'ambito del trunk del progetto, quindi anche le eventuali modifche alle librerie, saranno registrate in tale ambito

Una nuova versione della libreria

Come è ovvio che accada, ad un certo punto dello sviluppo del nostro progetto, vengono rilasciate nuove versioni delle librerie. E' desiderabile integrare le nuove versioni delle librerie nel progetto e quindi anche nel repository.

Questa operazione non è banale, perchè e' necessario integrare le nostre modifiche alla libreria con la nuova versione appena rilasciata.

Ad esempio, supponiamo che sia stata rilasciata la versione 2.2 di fftlib e che siamo interessati ad integrarla nel progetto.

Soluzione 1

Importare la nuova versione della libreria e riapplicare manualmente le personalizzazioni


fttlib-2.1 in vendor/fftlib-2.1

Copiare /vendor/fftlib-2.1 in /trunk/src/fftlib e riapplicare le personalizzazioni

DA COMPLETARE

Soluzione 2

DA COMPLETARE
Vota questa pagina:

1 Commenti:

#1 Inviato da giordano 01-09-2010

Ottimo post

Lascia il tuo commento:

Note:
  • La tua email non è obligatoria e non sarà visibile in alcun modo
  • Si prega di inviare solo commenti relativi a questa pagina
  • Commenti inappropriati o offensivi saranno modificati o eliminati
  • Codici HTML non sono consentiti. Prego usare i BB code:
    [b]bold[/b], [u]underline[/u], [i]italic[/i], [code]code[/code]
Il codice, le illustrazioni e gli esempi riportati in questa pagina sono solo a scopo illustrativo. L'autore non prende alcuna responsabilità per il loro utilizzo da parte dell'utente finale.
Questo materiale è di proprietà di Pk Lab ed è utilizzabile liberamente a condizione di citarne la fonte.