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!)

Sistemi di revisione concorrente del codice

Introduzione ai VCS - Subversion e Bazaar

Master "Tecnologie OpenSource"

Obiettivi

  • Conoscere i concetti di base di un VCS
  • Conoscere le origini e l’evoluzione dei VCS
  • Conoscere l’architettura di un sistema di revisione centralizzato
  • Utilizzare i comandi base di Subversion
  • Amministrare un server SVN
  • Conoscere la terminologia e l’architettura di un VCS distribuito
  • Capire le differenze tra VCS e DVCS
  • Utilizzare i comandi base di Bazaar (BZR)
  • Conoscere i comandi avanzati di Bazaar

Origine dei sistemi di revisione dei cambiamenti

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

  1. Configuration identification
  2. Configuration control
  3. Configuration status accounting
  4. Configuration authentication

Tali concetti sono stati adottati in diversi ambiti del management.

Evoluzione: da SCCS a RCS a CVS

Riferimenti:

Pratica: diff e patch

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

Introduzione ai VCS (1/3)

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)

Introduzione ai VCS (2/3)

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”

Introduzione ai VCS (3/3)

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.

Terminologia di base (1/2)

Terminologia di base (2/2)

(Wikipedia)

Limitazioni di CVS

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

La nascita di SVN

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.

Caratteristiche principali

La release 1.0 venne rilasciata il 23 febbraio 2004, e comprendeva le seguenti funzionalità:

Negli anni sono state aggiunte altre importanti caratteristiche:

Architettura di SVN

Architettura di SVN

  • il layer più in alto rappresenta i differenti client (da svn ai plug-in per eclipse)
  • tutti i client si appoggiano ad una libreria client sviluppata in seno al progetto, che offre API per la gestione del working tree
  • al di sotto della suddetta libreria vi è lo strato di accesso ai repositories, che può poggiarsi su protocolli di rete (WebDav, svn) o su filesystem (accesso in locale)
  • in caso di accesso remoto vi è poi una componente server side, rappresentata da soluzioni tra loro alternative come Apache Web Server, svnserve o un server SSH+svnserve
  • nel layer più basso trova spazio il repository vero e proprio, a sua volta poggiato su uno dei due backend supportati (BDB o FS)

Componenti di Subversion

Subversion è costituito da una serie di componenti che consentono la gestione dei repository e del working tree:

Revisione centralizzata

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.

Problemi nell’accesso concorrente

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?

Architettura di SVN

In figura è mostrato il classico problema di una corsa critica, dovuto all’accesso concorrente ad una risorsa condivisa

Paradigma lock-modify-unlock (1/2)

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.

lock-modify-unlock

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.

Paradigma lock-modify-unlock (2/2)

L’approccio lock-modify-unlock garantisce la consistenza dedlle modifiche in ogni circostanza, ma introduce notevoli svantaggi:

Modello copy-modify-merge (1/2)

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.

copy-modify-merge

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)

Modello copy-modify-merge (2/2)

copy-modify-merge

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

Repository Subversion

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.

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

Comandi di base (workflow 1/2)

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

Comandi di base (workflow 2/2)

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”

Aggiornare il working tree

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)

Stato del working tree

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)

Risoluzione dei conflitti

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:

svn resolved nome_file_in_conflitto

Solo dopo il resolved il sistema darà la possibilità di effettuare un commit

Nota: uno strumento grafico molto comodo per risolvere queste situazioni è meld

Pratica: prima interazione con svn

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, Merging e Tagging (1/2)

Branching, tagging, and merging sono concetti trasversali a tutti i sistemi di revisione.

branching

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.

Branching, Merging e Tagging (2/2)

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

Amministrare un repository SVN

La creazione di un repository SVN è un’operazione estremamente semplice. Subversion mette a disposizione dell’utente un comodo tool di amministrazione: svnadmin

svnadmin create nome_del_repository

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:

svn import directory_da_importare repository_da_utilizzare

Nota: è buona prassi creare directory di progetto con, al primo livello, tre rami: trunk, branches e tags

SVN – Docs

ARCHITETTURA:

  • http://svnbook.red-bean.com/en/1.1/ch01s04.html

TERMINOLOGIA:

  • http://www.tigris.org/nonav/scdocs/ddSVN_svnglossary.html

COMANDI BASE:

  • http://ariejan.net/svncheatsheet/
  • http://svnbook.red-bean.com/
  • http://itg.chem.indiana.edu/inc/wiki/software/287.html
  • http://www.yolinux.com/TUTORIALS/Subversion.html
  • http://www.developer.com/java/other/article.php/10936_3499816_1

SERVER:

  • http://www.linuxfromscratch.org/blfs/view/svn/server/svnserver.html
  • http://svnbook.red-bean.com/

Introduzione ai DVCS (1/2)

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)

Introduzione ai DVCS (2/2)

Il modello a Bazaar

<<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.>>

Wikipedia

Bazaar: un DVCS libero (1/2)

Bazaar è un sistema di revisione decentralizzato multipiattaforma.

Le sue principali caratteristiche sono:

Merging intelligente

Facile da usare

Intuitivo

Bazaar: un DVCS libero (2/2)

Molto ben integrato

Altamente configurabile

Flessibile

Architettura

Architettura Centralized VCS

Architettura Decentralized VCS

Terminologia di BZR

Workflow di BZR (1/2)

Solo e Peer2Peer Workflow

Centralized/Shared Workflow

Workflow di BZR (2/2)

GateKeeper Workflow

PQM Workflow

Comandi di base (1/2)

Inizializzazione

Manipolazione del filesystem

Controllo delle versioni

Comandi di base (2/2)

Merging

Pubblicazione

Ottenere informazioni

Risoluzione dei conflitti con bzr (1/3)

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.

Risoluzione dei conflitti con bzr (2/3)

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

Risoluzione dei conflitti con bzr (3/3)

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.

Prima interazione con bzr

# 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

Branching, Merging e Tagging… (1/2)

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.

Branching, Merging e Tagging… (2/2)

# 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

Accedere ad un repository remoto (1/2)

bazaar supporta molteplici modalità di interazione con i repository remoti. I protocolli attualmente supportati sono:

Accedere ad un repository remoto (2/2)

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.

Bazaar – Docs

ARCHITETTURA/WORKFLOW

  • http://bazaar-vcs.org/Workflows
  • http://bazaar-vcs.org/Tutorials/CentralizedWorkflow

TERMINOLOGIA:

  • http://bazaar-vcs.org/BzrGlossary

COMANDI BASE:

  • http://doc.bazaar-vcs.org/latest/en/mini-tutorial/index.html

COMANDI AVANZATI:

  • http://doc.bazaar-vcs.org/latest/en/user-guide/index.html
  • http://doc.bazaar-vcs.org/bzr.dev/en/user-reference/bzr_man.html

REFERENCE:

  • http://bazaar-vcs.org/BzrMigration
  • http://doc.bazaar-vcs.org/bzr.dev/en/quick-reference/quick-start-summary.pdf

Copyright (C) 2008 - Alca Societa' Cooperativa

http://alca.le.it - info@alca.le.it

released under CreativeCommons 2.5 by-nc-sa

NOTA: le immagini dei software e dei device contenuti
nella presentazione sono proprieta' dei relativi detentori
del copyright e sono state riprodotte a scopo esclusivamente didattico.