Issuu on Google+

Appunti Subversion

Pagina 1 di 7

Guida rapida a subversion Autore: Matteo Lucarelli ultima versione su: www.matteolucarelli.net

Breve guida all'uso di subversion Subversion (abbreviato svn) è un sistema di controllo del versionamento. Si utilizza principalmente sul codice sorgente, ma può funzionare con qualsiasi tipo di file. { { { { { {

Mantiene un indice (un numero naturale) che viene incrementato ad ogni modifica effettuata. Per ogni modifica mantiene autore, data, variazioni applicate, ecc. Permette di risalire alle versioni precedenti anche sui singoli file Permette di controllare le modifiche effettuate, di annullarle, ecc. Mette in sicurezza l'eventuale modifica contemporanea da parte di più persone Mette in sicurezza da cancellazioni accidentali, modifiche maldestre, ecc.

L'esistenza di un rapporto server client è necessaria al meccanismo di versionamento, che funziona essenzialmente controllando lo scambio tra i file sul server (repository) e quelli sul client (copia di lavoro). I file versionati non sono direttamente accessibili neanche dal server, infatti nelle cartelle dei repository si trovano in forma di database. Per accedervi è necessario creare un copia di lavoro locale. Naturalmente server e client possono anche risiedere sulla stessa macchina. In tal caso l'unica differenza consisterà nell'uso dell'indirizzo 127.0.0.1 (loopback) per riferirsi al server. L'indice di versione è globale del repository ma ovviamente il sistema tiene traccia delle modifiche di ogni file. Nell'organizzazione di un server svn si tenderà quindi a creare più repository, ognuno contenente un raggruppamento logico o funzionale di file (a esempio un repository per ogni progetto o gruppo di progetti affini). Qualsiasi operazione illustrata nel seguito ammette l'uso del flag (fondamentale) -r NUM -r NUM1:NUM2 che specifica la revisione, o l'intervallo di revisioni, a cui riferire l'operazione richiesta. In assenza di specifica si intende sempre l'ultima versione, cioè la più recente. inoltre alcune revisioni salienti sono identificate anche da etichette: { { {

HEAD: identifica l'ultima revisione del repository BASE: identifica l'ultimo aggiornatamento della copia di lavoro COMMITTED: identifica l'ultima revisione in cui un elemento ha subito modifiche

Tutti i comandi sono dotati di help in linea: svn help merge svnadmin help

: stampa l'help del sottocomando merge : stampa l'help generale di svnadmin

Risulta chiaro che avendo a disposizione un sistema di controllo delle versioni converrà effettuare un upload dei sorgenti sul server ogni volta che sia implementata una caratteristica completa, in modo da poter etichettare in modo chiaro ogni versione salvata. Non è necessario preoccuparsi dell'eventuale occupazione di disco conseguente ad un elevato numero di versioni, perchè il sistema limita l'effettiva scrittura fisica allo stretto necessario, quindi in generale non viene salvata una intera copia dei sorgenti ma solo le differenze con la versione precedente.

INSTALLAZIONE Utilizzando la modalità tunnel con ssh (che non è l'unica possibile) l'installazione e l'avvio sono quanto di più semplice: { {

{

Installare subversion Creare /var/svn/, ed eventualmente montarvi una partizione, con i giusti permessi NOTA: i permessi vanno posti come se si dovesse accedere ai repository in modo diretto, quindi le cartelle ed i file dovranno essere scrivibili dagli utenti che utilizzeranno l'svn. Verificare che il server ssh sia avviato

L'autenticazione sarà compito di ssh, che chiederà una password di sistema ad ogni accesso al server. L'inserimento della password ad ogni richiesta può risultare un po' noiso, ma tutto sommato è una buona norma di sicurezza e permette di distinguere chiaramente quando un'operazione viene effettuata sul server piuttosto che in locale. NOTA: utilizzando il tunnel ssh il servizio svn non deve essere avviato, perchè sarà il servizio ssh ad restare in ascolto delle connessioni. Eventuali script (/etc/rc o /etc/init) installati dal sistema andranno quindi rimossi.

http://www.matteolucarelli.net/svn/appuntisvn.htm

05/05/2011


Appunti Subversion

Pagina 2 di 7

L'umask di default, usando il tunnel ssh, viene settata a 002, quindi i file creati saranno leggibili a tutti ma modificabili solo dall'utente proprietario. Per modificare questo comportamento spostare il vero svnserve mv /usr/bin/svnserve /usr/bin/svnserve-real e creare uno script in sostituzione con il seguente contenuto #!/bin/sh umask 002 /usr/bin/svnserve-real "$@" che va reso eseguibile chmod 755 /usr/bin/svnserve

Scelte di installazione Nel seguito del testo si assumono: { { {

Repository posizionati sul server in /var/svn/ Utilizzo del servizio svnserve in modalità tunnel con ssh Utilizzo della modalità di memorizzazione di default

Oltre ad svnserve (incluso nel pacchetto) è possibile integrare il modulo con apache, utilizzando quindi il protocollo http. L'uso di svnserve in accoppiata con ssh ha il vantaggio di permettere l'autenticazione tramite gli account di sistema, quindi non è necessario inserire password e utenti. Nella maggior parte delle distribuzioni Linux inotre questa modalità non richiede alcuna installazione aggiuntiva. Dove necessario si assume per i repository il seguente layout: / |--trunk/ | |--dir/ | | \... | \... |--tags/ | |--dir/ | | \... | \... \--branches/ |--dir/ | \... \... con le directory trunk, tags e branches posizionate nella root del repository e contenenti la medesima struttura, non necessariamente completa. La struttura utilizzata è arbitraria e rispecchia le necessità del codice e dei progetti custoditi. Il codice principale è contenuto nella directory trunk, mentre tags e branches contengono rispettivamente delle versioni che si vogliono conservare, ad esempio delle release, e dei fork cioè dei rami di sviluppo differenziati. Per tale motivo non sono necessariamente complete, visto che per un certo progetto potrebbe non esistere alcun fork nell sviluppo.

USO L'uso si intende effettuato da una macchina remota in rete con il server. L'URL del repository avrà quindi la forma: svn+ssh://x.x.x.x/path/assoluto/sul/server dove x.x.x.x è ovviamente l'indirizzo del server. Se invece è necessario specificare l'utente: svn+ssh://utente@x.x.x.x/path/assoluto/sul/server

In generale per le operazioni locali è possibile usare sia path relativi che assoluti. Dove non si specifichi il path si intende di default la cartella corrente, quindi la maggior parte delle operazioni di lavoro andranno effettuate dall'interno della propria copia di lavoro. In generale il lavoro tramite svn prevede i seguenti passi: {

Download dell'ultima versione dei sorgenti e creazione di una copia di lavoro (checkout) oppure aggiornamento di

http://www.matteolucarelli.net/svn/appuntisvn.htm

05/05/2011


Appunti Subversion

Pagina 3 di 7

sorgenti già scaricati. svn co|update {

Modifiche in locale (oltre all'editing) svn add|delete|copy|move

{

Esame delle modifiche svn status|diff

{

Eventuale annullamento di modifiche svn revert

{

Eventuale risoluzione dei conflitti svn update|resolved

{

Upload delle modifiche sul server svn commit

Importazione Per listare la struttura del repository si utilizza il comando: svn list --verbose -R svn+ssh://x.x.x.x/var/svn/repository

Per creare una copia di lavoro di una parte di repository: svn co svn+ssh://x.x.x.x/var/svn/repository/trunk/path/to/project/ PROJECT l'operazione crea nella directory corrente una directory PROJECT contenente i file estratti dalla cartella "path/project/trunk" del repository. Da questo momento in poi non sarà più necessario specificare l'URL di origine dei dati, visto che ovviamente il sistema ne tiene traccia. Per creare una copia di lavoro di un intero repository: svn co svn+ssh://x.x.x.x/var/svn/repository l'operazione crea nella directory corrente una directory nominata come il repository contenente una copia completa. L'operazione di checkout va effettuata solo alla prima creazione della copia di lavoro. Successivamente per sincronizzare la copia locale con quella del repository (si noti che non è più necessario specificare l'URL): cd /path/della/copia/di/lavoro/ svn update l'output di update elenca i file convolti nell'aggiornamento. Ognuno dei file elencati è etichettato con una lettera: { { { { {

A: il file è stato aggiunto D: il file è stato cancellato U: il file è stato aggiornato G: il file è stato unito, ovvero le modifiche locali e remote sono state applicate senza conflitti C: il file è in conflitto, ovvero le modifiche locali e remote non sono applicabili automaticamente

I casi G e C segnalano la necessità di un controllo manuale (si veda la sezione Risoluzione dei conflitti).

Editing I file della propria copia di lavoro possono essere modificati liberamente. le operazioni di filesystem vanno invece segnalate al sistema svn. Per aggiungere un file o una directory già esistenti usare il comando: svn add file_or_dir se la directory aggiunta contiene dei file questi verranno automaticamente aggiunti a loro volta, per modificare questo comportamento usare il flag -N. Si noti che in assenza di specifica i file aggiunti durante il normale lavoro non verranno

http://www.matteolucarelli.net/svn/appuntisvn.htm

05/05/2011


Appunti Subversion

Pagina 4 di 7

uploadati sul server. Questa comportamento permette di non doversi preoccupare di eventuali file temporanei (file oggetto, dati di prova, ecc.) Per creare una nuova directory: svn mkdir directory

Per cancellare un file usare il comando: svn delete file

Per rinominare o copiare un file: svn move oldfile newfile svn copy file newfile

Tutte le operazioni illustrate possono accettare anche un URL come argomento. In tal caso l'operazione viene effettuata direttamente sul repository.

Analisi ed esportazione delle modifiche Per esportare i cambiamenti sul server si utilizza, dall'interno della copia di lavoro uno dei due comandi: svn commit -m "Commento" svn commit -F file_di_commento L'uso del commento in linea (-m) oppure di un file di commento (-F) è obbligatorio. In caso contrario verrà avviato automaticamente un editor per inserire il commento. La scelta dell'editor è modificabile nel file ~/.subversion/config E' possibile esportare anche singoli file: svn commit path/relativo/al/file

Nel caso in cui i sorgenti sul server siano stati modificati dall'ultima importazione si viene a creare un conflitto al momento dell'applicazione delle modifiche al repository. Svn avverte della situazione ed il commit fallisce. E' quindi necessario provvedere ad una analisi manuale (si veda la sezione Risoluzione dei conflitti). Prima di effetture una commit è comunque buona abitudine dare un'occhiata ai cambiamenti effettuati, anche solo per ideare un significativo messaggio di commento. Per interrogare sui cambiamenti effettuati localmente rispetto all'ultima update (si noti che il risultato è indipendente dall'attuale contenuto del repository in rete): svn status -v L'output del comando status comincia sempre con una lettera maiuscola che identifica la situazione del file elencato, i più comuni sono: { { { { {

A: il file è stato aggiunto C: il file è in conflitto D: il file è stato cancellato M: il file è stato modificato ?: il file è presente ma non è sotto controllo di versione

Per confrontare la versione locale con quella sul server si usa il comando: svn status -vu In particolare l'output di quest'ultimo comando segnala tramite un asterisco i file che sono stati aggiornati sul server: M M

* *

44 44 44

23 20 35

sally harry harry

README main.c utils.c

In questo caso è evidente che il commit genererà un conflitto sul file README, che è stato modificato localmente (segnale M) pur essendone disponibile una versione aggiornata nel repository (asterisco). Per avere un output dettagliato è disponibile il comando diff: svn diff svn diff file.txt

http://www.matteolucarelli.net/svn/appuntisvn.htm

: visualizzale modifiche locali dall'ultimo update : visualizza le modifiche a file.txt dall'ultimo update

05/05/2011


Appunti Subversion

Pagina 5 di 7

svn diff -r 5:BASE svn diff -r 5:6 svn diff URL@R1 URL@R2

: mostra le differenze tra la copia di lavoro e la rev 5 sul server : mostra le modifiche effettuate tra le revisioni 5 e 6 sul server : mostra le modifiche tra i due URL nelle revisioni R1 ed R2

L'output è quello standard per il comando diff, cioè riporta solo le differenze, marcando le linee eliminate con il carattere '-' e quelle aggiunte con il carattere '+'. L'output di diff è modificabile utlizzando i flag del comando standard (man diff). Ad esempio se si vuole un output a colonne parallele (molto più leggibile): svn diff --diff-cmd /usr/bin/diff -x -y

Il comando merge ha una sintassi analoga al comando diff, ma mentre il primo visualizza le differenze, il secondo le applica alla copia di lavoro. Quindi: svn merge -r A:B http://x.x.x.x/repository/path applica le differenze tra le revisioni A e B del repository indicato alla copia di lavoro attuale. Questo comando è utile per annullare modifiche precedenti- Ad esempio se A è maggiore di B verranno rimosse dalla copia di lavoro le modifiche effettuate tra la revisione B e la A. Per visualizzare la storia delle modifiche di un file, o di un intero repository si utilizza il comando log: svn svn svn svn

log log -v log file log -r a:b

: : : :

mostra mostra mostra mostra

il il il il

log log log log

sintetico completo relativo ad un file limitato all'intervallo di revisioni a-b

Il comando log agisce sempre sul repository remoto. Quando il path specificato è locale mostra la storia del file nel repository originario. Se non si specificano versioni si intende da 1 a BASE della copia locale.

Risoluzione dei conflitti Visto che il sistema di versionamento non può entrare nel merito del contenuto dei file esistono casi che richiedono un intervento manuale. In particolare ciò avviene quando una modifica locale si sovrappone a modifiche sul server effettuate successivamente alla nostra ultima update. Il caso più semplice viene risolto eliminando i cambiamenti locali, cioè riportando la situazione all'ultimo update tramite il comando: svn revert dir_o_file

Negli altri casi si procederà come segue. 1. Aggiornare i sorgenti svn update nell'output del comando update il conflitto è segnalato con una C. Subversion provvede quindi a creare tre versioni del file in conflitto: FILE.mine FILE.rOLD FILE.rNEW

: versione presente nella copia di lavoro prima dell'update : versione precedente alle modifiche della copia di lavoro : versione attualmente presente sul server

oltre a inserire nella copia originale dei markers: <<<<<< .mine // linee presenti nella versione in conflitto ======= // linee presenti nella versione sul server >>>>>> .r2 Disponendo dei tre file è quindi possibile analizzare i cambiamenti che hanno dato luogo al conflitto. 2. Dopo avero corretto il problema e modificato il file originale impartire il comando: svn resolved FILE che provvede a rimuovere i file temporanei e ad informare subversion della risoluzione del problema. 3. A questo punto si può effettuare una nuova commit.

AMMINSTRAZIONE I comandi svnadmin e svnlook vengono utilizzati sul server, quindi non attraverso la rete. I path utilizzati sono quindi percorsi locali e possono essere sia assoluti che relativi.

http://www.matteolucarelli.net/svn/appuntisvn.htm

05/05/2011


Appunti Subversion

Pagina 6 di 7

Creazione ed eliminazione di un repository Per creare un repository: svnadmin create /var/svn/projectname

Per importare un progetto creare in una cartella temporanea la struttura base del repository: mkdir mkdir mkdir mkdir

/tmp/projectname /tmp/projectname/branches /tmp/projectname/tags /tmp/projectname/trunk

quindi copiare tutti i file (e l'eventuale struttura di directory) nella cartella /tmp/projectname/trunk/. A questo punto impartire il comando di importazione: svn import /tmp/projectname file:///var/svn/projectname -m "Versione Iniziale" NOTE: { {

la struttura trunk/branches/tags è lo standard consigliato, non è obbligatoria il flag -m (messaggio) è necessario e può essere sostituito dal flag -F seguito dal path di un file di testo usato come commento.

Per eliminare un repository è sufficiente cancellare la sua directory: rm -rf /mnt/svn/projectname

Backup Il backup può essere fatto in diversi modi: { { { {

Usando il comando 'svn co', cioè effettuando una estrazione dei file limitata ad una specifica revisione. Meglio ancora è l'utilizzo del comando 'svn export' che crea una copia non versionata, eliminando cioè tutti i file specifici di svn. Tramite dump Copiando il contenuto del repository

gli ultimi due sistemi permettono di salvare anche tutte le informazioni di revisione. Per effettuare un dump, ovvero un file di testo contenente tutte le informazioni: svnadmin dump /path/del/repository > dump-file E' naturalmente possibile fare il dump di una revisione o di un intervallo di revisioni: svnadmin dump /path/del/repository --revision N > dump-file svnadmin dump /path/del/repository --revision N1:N2> dump-file Il dump potrà successivamente essere caricato in un repository con il comando: cat dump-file > svnadmin load /path/del/repository Le due operazioni possono anche essere messe in pipe: svnadmin dump repository1 | svnadmin load repository2

Per modificare i dump esiste inoltre un comando specifico, svndumpfilter, utlizzabile ad esempio per isolare un singolo progetto: cat dump-file | svndumpfilter include project > dump-file-parziale

Per effettuare una copia del repository si possono semplicemente copiare i file. In modo più sicuro, su un repository in uso, si può usare il comando: svnadmin hotcopy /path/del/repository /path/del/backup

http://www.matteolucarelli.net/svn/appuntisvn.htm

05/05/2011


Appunti Subversion

Pagina 7 di 7

Branch e Tag La creazione di branch e tag consiste essenzialmente nella duplicazione delle informazioni del repository in una nuova destinazione. I branch vengono utilizzati per il mantenimento di versioni parallele, ad esempio dei fork del codice principale, mentre i tag per conservare delle istantanee di particolari versioni, ed esempio delle release. L'unica differenza tra le due operazioni consiste quindi nel fatto che un tag si suppone congelato al momento della sua creazione, mentre un brach continuerà ad essere sviluppato, e quindi versionato. L'operazione di creazione di un branch o di un tag può essere effettuata in remoto tramite un singolo comando che effettua un commit immediato della modifica: svn copy svn+ssh://x.x.x.x/var/svn/repository/trunk/percorso/nome_progetto/ \ svn+ssh://x.x.x.x/var/svn/repository/branches_o_tags/percorso/nome_branch_o_tag/ \ -m "Creazione del nuovo branch o tag nome_branch_o_tag del progetto nome_progetto"

Dopo la creazione un brach o un tag continuerà a condividere il numero di versione (che è globale del repository), ma le storie delle variazioni saranno separate (facendo il log di uno specifico ramo si visualizzano solo le revisioni che lo hanno modificato). Esistono diversi modi per evitare che un tag venga modificato dopo la sua creazione, in ogni caso ciò non è normalmente necessario, visto che in ogni momento le modifiche possono essere annullate. Per applicare delle variazioni effettuate su un altro ramo di sviluppo è si utilizza il comando merge. matteolucarelli.net ©opyright info

http://www.matteolucarelli.net/svn/appuntisvn.htm

05/05/2011


svn