Microsoft's Internet Explorer browser has no built-in vector graphics machinery required for "loss-free" gradient background themes.
Please upgrade to a better browser such as Firefox, Opera, Safari or others with built-in vector graphics machinery and much more. (Learn more or post questions or comments at the Slide Show (S9) project site. Thanks!)
Le origini dei VCS/SCM (Version Control System – Software Code/Change/Configuration Manager) sono da ricercarsi agli inizi degli anni 50, quando il Dipartimento della Difesa Americano sviluppò una disciplina per la gestione dei cambiamenti a sistemi complessi detta Configuration Management.
“en.wikipedia.org > Wiki > Configuration management”:http://en.wikipedia.org/wiki/Configuration_management
Tali concetti sono stati adottati in diversi ambiti del management.
Riferimenti:
Su tutte le distribuzioni GNU/Linux abbiamo a disposizione i tool diff e patch che oltre a consertirci una migliore comprensione dei concetti alla base dei VCS, si possono rivelare utili in molte situazioni (anche a prescindere dalla gestione dei codici sorgente)
diff -u orig dest patch -p0 < orig-to-dest.diff
Il controllo delle revisioni (altrimenti noto come “sistema di controllo delle versioni” (VCS) o “sistema di gestione del codice sorgente” (SCM)) permette l’organizzazioni e la gestione di differenti versioni delle stesse informazioni.
I sistemi VCS sono largamente usati nell’ingegneria e nello sviluppo software per tracciare le modifiche alle risorse utilizzate (in generale il codice sorgente, ma i VCS non si limitano a questo)
Una delle caratteristiche trasversali a tutti i VCS è la capacità di gestire le modifiche alle risorse revisionate attraverso la rete. Questi strumenti permettono dunque a più persone, non necessariamente presenti nello stesso luogo geografico di lavorare parallelamente allo stesso progetto, e di gestire in maniera più o meno complessa le modifiche a file condivisi.
In prima analisi si può quindi pensare ad un VCS come ad un file server con alcune importanti caratteristiche aggiuntive:
Le ultime due caratteristiche inducono a guardare al VCS come a una sorta di “macchina del tempo”…
Tradizionalmente, i sistemi di controllo di versione hanno usato un modello centralizzato, in cui tutte le funzioni di controllo di versione sono eseguite da un server condiviso (repository).
In questo paradigma, il server, unico, tiene traccia delle risorse e dello storico delle revisioni, e i client (in numero indefinito) consentono di lavorare sulle risorse condivise attraverso un meccanismo di copia locale (o working-tree).
Negli ultimi anni si è imposto un modello di revisione distribuito, in cui ogni sviluppatore lavora direttamente con il suo repository locale, e le modifiche sono condivise tra i repository in un passo separato. Questa modalità di operare permette di lavorare senza una connessione di rete.
Nota: la maggior parte dei VCS usano la compressione delta, che conserva solamente le differenze fra le versioni successive dei file. Questo consente un immagazzinamento efficiente di più versioni di un file, purché, come solitamente succede, le modifiche tra una versione e la successiva riguardino solamente una piccola parte del testo.
GNU CVS è stato per moltissimo tempo il sistema di revisione dei sorgenti libero. Tuttavia con il passare del tempo le sue limitazioni (molte derivanti da precise decisioni implementative del progetto) cominciavano a farsi sentire:
Fonti: http://en.wikipedia.org/wiki/Concurrent_Versions_System#Limitations
Subversion (noto anche come svn, che è il nome del suo client a riga di comando) è un sistema di controllo di versione progettato da CollabNet Inc. con lo scopo di essere il naturale successore di CVS, oramai considerato superato.
Lo sviluppo di subversion inizia nel 2000, con l’intento di implementare un VCS libero che operasse come CVS, ma ne superasse le limitazioni. Dal 2001 subversion è diventato sufficientemente stabile e funzionale, da poter revisionare il suo stesso codice.
Subversion è rilasciato sotto varie licenze (librerie, client cli, tools di amministrazione del repository, etc.), tra cui Apache License, GPL v2 e una variante della Apache License.
La release 1.0 venne rilasciata il 23 febbraio 2004, e comprendeva le seguenti funzionalità:
Negli anni sono state aggiunte altre importanti caratteristiche:
Subversion è costituito da una serie di componenti che consentono la gestione dei repository e del working tree:
Subversion è un sistema centralizzato per la condivisione delle informazioni, basato sul paradigma di interazione client/server. Al centro c’è il repository, che è l’archivio principale di dati. Il repository memorizza informazioni sotta forma di un filesystem ad albero (la tipica gerarchia di file e directory).
Quando un client legge i dati dal repository, normalmente vede solo l’ultima versione dell’albero del filesystem. Il client in realtà ha anche la possibilità di vedere uno stato precedente del filesystem. Ad esempio, un client può chiedere domande storiche come «Cosa conteneva questa directory l’ultimo Mercoledì?» oppure «Chi è stata l’ultima persona a cambiare questo file, e che modifiche ha apportato?». Queste sono le tipologie di domande che sono alla base di qualsiasi sistema di controllo di versione: sistemi che sono progettati per registrare e tenere traccia delle modifiche ai dati nel tempo.
Tutti i sistemi per il controllo di versione devono risolvere lo stesso problema fondamentale: come farà il sistema a permettere agli utenti di condividere le informazioni, evitando al contempo che questi possano accidentalmente interferire fra loro?
In figura è mostrato il classico problema di una corsa critica, dovuto all’accesso concorrente ad una risorsa condivisa
La soluzione più semplice, implementata in molti dei primi VCS, si basa sull’utilizzo dei lock. In questo modello, il repository permette la modifica di un file solo ad un utente per volta.
Secondo questo workflow, un utente, prima di modificare una risorsa revisionata, deve acquisirne un lock per inibirne l’accesso agli altri utenti.
Nel lasso di tempo in cui chi ha acquisito un lock lavora su un file, nessun altro potrà accedere allo stesso, neanche in lettura.
L’approccio lock-modify-unlock garantisce la consistenza dedlle modifiche in ogni circostanza, ma introduce notevoli svantaggi:
Subversion utilizza il paradigma copia-modifica-fondi come alternativa al blocco. In questo modello, ciascun client crea il proprio working tree (una riproduzione locale del repository centralizzato).
Gli utenti possono così lavorare in parallelo, modificando le proprie copie private, che solo in una fase successiva verranno fuse in una nuova versione finale.
Harry e Sally ottengono un working tree dallo stesso repository ( check-out )
Entrambi modificano uno stesso file (A), ma ciascuno nella propria copia locale ( change )
Sally aggiorna per prima il repository remoto, inviando la sua copia ( A’’ ) ( commit di una nuova revisione )
Harry tenta di inviare al repository le proprie modifiche ( A’ ), ma il sistema lo blocca (out-of-date)
Harry aggiorna allora il proprio working tree, scaricando la revisione di Sally ( update ). A questo punto possiede in locale entrambe le nuove revisioni ( A’ e A’’ )
Harry fonde le due versioni ( merge ) producendo una nuova revisione ( A * ), e la invia al repository ( commit )
Sally può ora aggiornare la propria copia locale ( update ), riallineandosi allo stato di Harry e del repository
Un tipico repository di Subversion spesso contiene i file (o codice sorgente) di diversi progetti; di solito, ogni progetto è contenuto in una sottodirectory nell’albero del filesystem del repository. Seguendo questa disposizione, la copia di lavoro di un utente corrisponderà ad uno specifico sottoalbero del repository.
All’interno di un repository SVN le informazioni storiche sono organizzate attraverso i numeri di revisione (successione dei numeri naturali)
Per pubblicare le proprie modifiche sul repository centrale si deve ricorrere all’operazione di commit.
Come risultato si ottiene la creazione di una nuova revisione e la sincronizzazione del repository su tale versione (con relativo spostamento dell’ HEAD )
Nota: ogni commit viene trattato come un’operazione atomica
Una tipica sessione di lavoro con svn si svolge grossomodo nei seguenti passi: (si suppone di aver già creato il proprio working tree da un repository remoto)
Passo 1: aggiornamento del W-T
Passo 2: Modifica al file system
Passo 3: Controllo dei cambiamenti apportati al W-T
Passo 4: Controllo degli aggiornamenti sul repository
Passo 5: invio della nuova revisione
Nota: il passo 5 è attuabile perché si suppone che l’update al passo 4 abbia restituito un risultato “up-to-date”
Segue una lista dei simboli con cui Subversion caratterizza i file in seguito ad un update:
U | File aggiornato con con successo |
A | File o directory aggiunto |
D | File o directory cancellati |
R | File o directory sostituiti |
G | File con modifiche locali e remote integrate con successo in modo automatico (merged) |
C | File con modifiche locali e remote non integrabili automaticamente (conflitto) |
In questa tabella sono elencati i possibili messaggi del comando svn status:
A | File, directory o link segnati per essere aggiunti al repository |
C | Elemento in stato di conflitto |
D | File, directory o link schedulati per la rimozione dal repository |
M | Elemento modificato localmente |
R | File, directory o link segnati per essere sostituiti nel repository |
X | Elemento non revisionato, ma collegato ad una definizione esterna di subversion |
? | Elemento non revisionato (andrebbe aggiunto con il comando svn add) |
! | Elemento presente sul repository ma cancellato in locale senza un svn remove |
~ | Il tipo di elemento in locale è diverso da quello remoto (file/directory) – non è stato usato il comando svn replace |
I | Elemento non revisionato, ma configurato per essere ignorato (svn ignore) |
Come abbiamo visto, si verifica un conflitto quando sussistono modifiche non integrabili automaticamente su uno stesso elemento sia sulla copia locale che sul repository centrallizzato.
Prima di effettuare un commit occorre SEMPRE fare un update per controllare che non si introducano situazioni di conflitto. Qualora il risultato di tale operazione marchi un file come conflittuale, verrano creati tre nuovi file nel proprio working tree: file.rx, file.mine e file.ry.
Per risolvere questa situazione occorre rimaneggiare tale risorsa e, una volta certi della modifica, lanciare il comando:
Solo dopo il resolved il sistema darà la possibilità di effettuare un commit
Nota: uno strumento grafico molto comodo per risolvere queste situazioni è meld
In questa sessione vogliamo creare una working copy da un repository già disponibile, leggerne la storia, effettuare delle modifiche ad un file e farne il commit…
# check-out di un progetto da un repository esterno svn co file:///tmp/repo/trunk project svn log # modifica a file e filesystem svn copy editing.. svn status svn update svn commit svn log
Branching, tagging, and merging sono concetti trasversali a tutti i sistemi di revisione.
Un branch è una linea di sviluppo che esiste independemente da un’altra, anche se entrambe condividono una storia comune se si guarda abbastanza indietro in tempo.
Un branch inizia la sua esistenza sempre come copia di qualcosa già presente nel repository, e prosegue da questo punto generando la sua propria storia…
Nota: Subversion non ha un concetto interno di branch, ma soltanto di copie. Quando si copia una directory, il risultato è un branch perché le viene dato questo significato.
Per merging si intende l’operazione di fusione tra risorse appartenenti a due branch distinti.
Il concetto di tag è strettamente correlato al ciclo di rilascio di un SW. Normalmente lo sviluppo si esegue sul trunk, prima di rilasciare una versione si crea un branch su cui eseguire test e correzioni (ad es. 1.0), e alla fine del ciclo di test si crea una copia in tags che rappresenta una release (tags/1.0.0) del progetto. La manutenzione correttiva continua sul ramo in branches, e le modifiche vengono portate in tags quando si decide di rilasciare una nuova mino release (tags/1.0.1)
Comandi per operazioni di branch, merge, e tag:
svn copy origine destinazione svn merge -r1:2 branch_left [branch_right] [working tree] svn copy (!)
Nota: svn merge è simile ai comandi diff e patch, ma gestisce anche le modifiche al FS
La creazione di un repository SVN è un’operazione estremamente semplice. Subversion mette a disposizione dell’utente un comodo tool di amministrazione: svnadmin
A questo punto il sistema è pronto ad accogliere risorse da revisionare. L’amministratore adesso ha facoltà di scegliere che tipo di accesso offrire all’esterno (WebDav, ssh+svnserve, svnserve). Resta comunque sempre utilizzabile l’accesso in locale, attraverso il protocollo file://
Una volta creato un repository, non resta che importarci un progetto; ciò è facilmente ottenibile con il comando:
Nota: è buona prassi creare directory di progetto con, al primo livello, tre rami: trunk, branches e tags
I sistemi di revisione distribuiti (DVCS) sono la più recente evoluzione nell’ambito dei sistemi di revisione del codice.
I DVCS nascono per superare alcune limitazioni dei sistemi di revisione classici (basati su un architettura client-server) ma soprattutto per consentire dei workflow più adeguati alle modalità di sviluppo di software complessi (e alle complesse interazioni sul codice che avvengono nello sviluppo di software libero)
<<Nel modello a Bazaar il codice sorgente della revisione in sviluppo è disponibile liberamente, gli utenti possono interagire con gli sviluppatori e se ne hanno le capacità possono modificare e integrare il codice. Lo sviluppo è decentralizzato e non esiste una rigida suddivisione dei compiti: un programmatore di buona volontà può modificare e integrare qualsiasi parte del codice. In sostanza lo sviluppo è molto più anarchico e libero, da qui il nome di modello a Bazaar. Il Kernel Linux e molti programmi utilizzano questo nuovo modello di sviluppo associativo.>>
Bazaar è un sistema di revisione decentralizzato multipiattaforma.
Le sue principali caratteristiche sono:
Merging intelligente
Facile da usare
Intuitivo
Molto ben integrato
Altamente configurabile
Flessibile
Inizializzazione
Manipolazione del filesystem
Controllo delle versioni
Merging
Pubblicazione
Ottenere informazioni
Uno strumento di fondamentale importanza messo a disposizione da bzr consiste nell’algoritmo di intersezione delle revisioni (merge).
Supponiamo di aver scaricato il branch di un progetto dal repository pubblico di quest’ultimo e di aver effettuato alcune modifiche.
Mentre noi procedevamo con l’implementazione nella nostra copia locale, e’ plausibile che nel frattempo qualcun altro abbia contribuito allo sviluppo del progetto pubblicando alcuni cambiamenti nel repository ufficiale.
Le modifiche effettuate su entrambi i branch segnano un punto di divergenza tra il repository pubblico e il nostro working tree locale. Ora supponiamo di voler unire questi due branch. In particolare, vogliamo “fondere” il branch pubblico sul nostro branch locale.
Ci affidiamo quindi al comando merge:
# bzr merge
Se l’algoritmo di merging non incontra conflitti durante la fase di fusione delle versioni allora non è richiesto alcun intervento da parte dello sviluppatore e si può precedere al commit:
# bzr commit
In caso di conflitto bzr aggiunge al nostro working tree tre file secondo il seguente schema:
nomefile.BASE, nomefile.THIS, nomefile.OTHER
Tali file rappresentano rispettivamente la base comune prima del verificarsi della divergenza, il file presente sulla nostra working copy, il file presente sul branch da cui abbiamo effettuato il merge (il branch remoto).
Inoltre, nel file oggetto del conflitto, mediante una sintassi particolare, viene identificato il punto in cui si è verificata la divergenza tra le revisioni.
# bzr init myproject # bzr add somefile # bzr commit -m 'primo commit' # modifica al working tree # bzr status # bzr commit -m 'commit delle modifiche' # bzr status
Come abbiamo visto, una branch è una linea di sviluppo di un progetto.
Il processo di branching consiste nel clonare una branch esistente in modo da proseguire uno sviluppo autonomo locale.
Il processo di fusione tra due branch si dice merging.
Il processo di tagging consiste nell’assegnare un nome ad una particolare revisione.
# bzr branch url_repository # bzr log # modifica al working tree # bzr status # bzr commit -m 'descrizione della modifica' # bzr missing # bzr merge # bzr diff # bzr commit -m 'descrizione del merge' # bzr tag nome_revisione
bazaar supporta molteplici modalità di interazione con i repository remoti. I protocolli attualmente supportati sono:
Supponiamo di voler clonare il branch di sviluppo del progetto bazaar. Il comando da eseguire è il seguente:
# bzr branch http://bazaar-vcs.org/bzr/bzr.dev bzr.dev
In questo caso il protocollo di trasmissione utilizzato è il classico http.