====== Subversion ======
Un libro su **[[http://svnbook.red-bean.com/index.en.html|Subversion]]**.
Elencare il contenuto di una directory su un repository:
svn list svn://svn.debian.org/pkg-grass/packages/grass/branches/
Prelevare una directory:
svn checkout svn://svn.debian.org/pkg-grass/packages/grass/branches/6.2~beta1/debian
Se il repository è su filesystem locale:
svn checkout file:///home/niccolo/src/svn/pyppp
In ogni directory prelevata tramite il comando **''checkout''** è presente anche una directory di nome **''.svn''** che contiene informazioni utilizzate da SVN per gestire la sincronizzazione della propria //working copy// con il repository. Se non vogliamo una //working copy// ma una semplice copia della directory è opportuno usare il comando **''export''** invece di **''checkout''**.
Per recuperare una **specifica revisione**:
svn --revision 13266 checkout https://svn.osgeo.org/qgis/trunk/qgis qgis-svn13266
===== SourceForge.net =====
Questa è la sintassi per prelevare con un **checkout anonimo** tutto il codice di un progetto dal sito SourceForge.net. Ad esempio usiamo il progetto **[[https://sourceforge.net/projects/mtkbabel/]]**:
svn checkout svn://svn.code.sf.net/p/mtkbabel/code
Nella directory corrente viene creata la directory **code** con tutta la gerarchia. Avendo fatto un **checkout anonimo** in generale non è possibile fare dei commit o modifiche al repository. Per fare un **checkout autenticato** si usa la sintassi:
svn checkout svn+ssh://niccolo@svn.code.sf.net/p/mtkbabel/code
Dopo aver modificato il codice si può eseguire il **commit**:
svn commit -m "Workaround for that very strange bug."
Se si è **caricata la propria chiave SSH** sul server di SourceForge (//Me//, //Account Settings//, //SSH Settings//), non viene richiesta la password.
===== Logical directories =====
Subversion shows 3 logical directories:
^ trunk | The current development branch |
^ branches | Branches for bugfixing stable releases |
^ tags | Contain the releases |
If you want the 'normal' svn branch, you will need to extract the ''trunk'' dir. The directory will be named //trunk//, but you are free to rename it after the initial checkout.
svn co svn+ssh://svn@svn.cpe.fr:/svn/wzdftpd/trunk
If you want a particular release, just extract the correct directory in the ''tags/'' subdir (remember you can list releases using the ''list'' command) ex:
svn co svn+ssh://svn@svn.cpe.fr:/svn/wzdftpd/tags/rel-0-5-3
====== Creare un repository locale ======
Per creare il repository è necessario avere accesso diretto al filesystem:
svnadmin create /usr/local/svn/newrepos
Le prime azioni (ad esempio creare la classica struttura di directory) possono avvenire tramite uno dei protocolli remoti, in questo esempio si usa **''%%file://%%''**, ma funziona ugualmente con **''%%svn+ssh://%%''**:
svn mkdir file:////usr/local/svn/newrepos/trunk
svn mkdir file:////usr/local/svn/newrepos/branches
svn mkdir file:////usr/local/svn/newrepos/tags
Importa in un repository (tramite il protocollo locale ''%%file://%%'') una directory:
svn import mytree file:///usr/local/svn/newrepos/trunk -m "Initial import"
====== Lavoro su una working copy ======
Crea una working copy del repository, sposta un file nella working copy, verifica quali sono i cambiamenti effettuati e poi fa il commit verso il repository:
svn checkout file:////usr/local/svn/pyppp
svn move pyppp/PyPPP pyppp/trunk/
svn status pyppp
svn commit -m "Create proper directory structure" pyppp/
Qui si aggiungono due nuovi file alla working copy e si effettua il commit.
cd /usr/local/src/pyppp/trunk
cp /some/location/pyppp.desktop .
cp /some/location/pyppp.png .
svn add pyppp.desktop
svn add pyppp.png
svn status
svn commit -m "Add a desktop file and icon."
Se qualcun'altro ha modificato il repository, con **update** si aggiorna la working copy:
svn update
====== Tag e branch ======
In Subversion i **tag** e i **branch** non sono niente più che copie di una directory. Sono gli sviluppatori che attribuiscono un significato a queste copie.
Ad esempio un **tag** è una copia del ramo principale di sviluppo (solitamente il **trunk**) che non viene più modificata, spesso utilizzata per marcare il rilascio di una versione.
Un **branch** invece è una copia del ramo principale (**trunk**) sulla quale apportare modifiche indipendenti da quelle principali. Ad esempio i fix su una versione rilasciata avvengono su un branch apposito, permettendo agli sviluppatori di continuare liberamente il lavoro principale sul trunk.
Ecco come derivare un tag dal trunk corrente:
svn copy \
svn+ssh://niccolo@svn.projects.openmoko.org/svnroot/pyppp/trunk \
svn+ssh://niccolo@svn.projects.openmoko.org/svnroot/pyppp/tags/0.1 \
-m "Tagging the first public release."
Dopo aver creato un tag (nuova directory) sul repository, in genere si deve aggiornare la working copy locale con **''svn update''**.
Se invece si lavora sulla working copy locale:
svn copy trunk tags/0.2
svn commit -m "Tagged release 0.2."
La prassi comune prevede di **usare il numero di versione** come nome della directory **tag** o **branch**, questo è il modo preferibile per SourceForge. Una alternativa è usare lo schema ''nomeprogetto-versione''.
====== Replica (mirror) di un repository ======
Interessante articolo: **[[http://wordaligned.org/articles/how-to-mirror-a-subversion-repository|How to mirror a subversion repository]]**. Nel libro //Version Control with Subversion// cercare **Repository Replication**.
===== hotcopy, dump e load =====
Se abbiamo accesso diretto al filesystem dove risiede il repository possiamo usare la funzione ''**hotcopy**'' di ''svnadmin'':
svnadmin hotcopy \
/home/niccolo/src/svn/pyppp \
/usr/local/svn/pyppp
Funziona agendo direttamente sul filesystem (non tramite i protocolli **''%%file://%%''** oppure **''%%svn+ssh://%%''**). Però ha il vantaggio di copiare - oltre ai file sottoposti a versioning - anche le informazioni accessorie, come gli hook scripts, etc.
La directory destinazione può essere vuota e non è necessario che abbia la struttura di repository.
In alternativa, sempre se si ha accesso al filesystem, si possono usare le funzioni ''**dump**'' e ''**load**'' di ''svnadmin'':
svnadmin dump /home/niccolo/src/svn/pyppp \
| svnadmin load /usr/local/svn/pyppp
In questo caso però **non vengono copiati gli oggetti** fuori dal sistema di versioning, inoltre la directory destinazione deve avere già la struttura di repository.
===== svnsync =====
Se l'accesso ai repository avviene tramite uno dei protocolli supportati (**''svn://''**, **''svn+ssh://''**, ecc.), si può utilizzare **''svnsync''**. In tal caso però **è praticamente obbligatorio** che l'accesso al repository destinazione venga fatto **solo via ''svnsync''**, ogni altra modifica effettuata sul repository destinazione potrebbe confondere il protocollo di versioning.
Per i dettagli vedere **Repository Replication** sul libro.