Svn

Page last edited 647 giorni 6 ore fa
Da wiki.betaingegneria.it.

Eccomi qui ad affrontare un quarto strumento per il controllo del versionamento del software, a dire il vero molto popolare, il più popolare prima dell'avvento di Git: SVN (Subversion Versioning Control).

Subversion è un software sviluppato da Apache e il popolare comando svn è la sua implementazione in linea di comando. In questo sito si trova tutto, manuali, repository da cui scaricare i tarball, istruzioni per l'installazione.

Qui riproduco il mio howto personale, come al solito.

Creazione del repository[modifica]

Questa operazionie va fatta non molto spesso: solo quando si vuole creare un nodo SVN che serva da archivio delle versioni. È piuttosto una operazione una tantum. Le istruzioni che seguono intendono che il repository sia LOCALE (nella stessa macchina fisica in cui si sta lavorando)

  $ cd && cd workspace
  $ svadmin create svnrepo
  $ ls svnrepo/
  conf  db  format  hooks  locks  README.txt

Attenzione!!![modifica]

In tutto ciò che segue repository è l'archivio centralizzato. Quindi IMPORTARE vuol dire caricare codice NEL repository:

            IMPORT
  Client ==========>> SVN Repository

La direzione del flusso nelle operazioni pertanto è

            CHECKOUT
  Client <<========== SVN Repository
            COMMIT
  Client ==========>> SVN Repository

Come preparare l'applicazione[modifica]

Suppongo di avere la mia applicazione sotto /var/www/test. Per farla digerire a SVN occorre però strutturarla come vuole lui; e cioè così:

  marcob@js:/var/www$ tree test
  test
  ├── branches
  ├── tags
  └── trunk

Quindi ci sono fondamentalmente tre directory vuote all'inizio. Il software che scrivo va messo dentro alla directory trunk:

  $ ls trunk/
  index.php  smarty/  stile.css

Come eseguire la prima importazione nel repository svn[modifica]

Con questo comando vogliamo importare una applicazione già ad un certo stadio di sviluppo in un sistema di versionamento per cominciare ad essere versionata.

Esistono i file sciolti ma non sono ancora sotto versionamento in un qualche repository, locale o remoto. È la situazione classica che c'è ad inizio dello sviluppo di un progetto.

Si ricordi sempre che IMPORT va dal client al server SVN (non il contrario!)

In sostanza il comando è

  $ svn import directory_di_sviluppo_locale directory_di_svn_locale_o_remota

Per semplicità per ogni direcory di sviluppo uso lo stesso nome svnrepo, e in questo caso il repository è nella stessa macchina in cui sto sviluppando (protocollo file://):

  $ svn import /var/www/test file:///home/marcob/workspace/svnrepo/test -m "initial import"
  Aggiungo       branches
  Aggiungo       tags
  Aggiungo       trunk
  Aggiungo       trunk/stile.css
  Aggiungo       trunk/index.php
  Aggiungo       trunk/smarty
  
  Committed revision 1.

Effettivamente il repository non si adegua in modo visibile alla mia struttura mentale:

  marcob@js:~/workspace$ tree svnrepo
  svnrepo
  ├── conf
  │   ├── authz
  │   ├── passwd
  │   └── svnserve.conf
  ├── db
  │   ├── current
  │   ├── format
  │   ├── fsfs.conf
  │   ├── fs-type
  │   ├── min-unpacked-rev
  │   ├── rep-cache.db
  │   ├── revprops
  │   │   └── 0
  │   │       ├── 0
  │   │       └── 1
  │   ├── revs
  │   │   └── 0
  │   │       ├── 0
  │   │       └── 1
  │   ├── transactions
  │   ├── txn-current
  │   ├── txn-current-lock
  │   ├── txn-protorevs
  │   ├── uuid
  │   └── write-lock
  ├── format
  ├── hooks
  │   ├── post-commit.tmpl
  │   ├── post-lock.tmpl
  │   ├── post-revprop-change.tmpl
  │   ├── post-unlock.tmpl
  │   ├── pre-commit.tmpl
  │   ├── pre-lock.tmpl
  │   ├── pre-revprop-change.tmpl
  │   ├── pre-unlock.tmpl
  │   └── start-commit.tmpl
  ├── locks
  │   ├── db.lock
  │   └── db-logs.lock
  └── README.txt

Se invece il repository è centralizzato da qualche parte nel cloud, occorrerà scrivere i miei file nel server remoto, quindi, per esempio:

   $ svn import /var/www/test http://some.svn.server.com/test -m "initial import"

È utile tenere sempre presente che con i comandi di SVN l'origine del sistema di riferimento è sempre il SERVER (e mai il client):

  • import è rispetto al server quindi i file entrano in SVN (escono dal mio computer)
  • checkout è rispetto al server quindi i file escono dal server SVN (ed entrano nel mio computer)

Estrarre una copia di lavoro e iniziare a sviluppare[modifica]

La copia di lavoro la posso estrarre in qualsiasi posto, sarebbe logico farlo in /var/www/test ma invece provo in un'altra posizione ancora:

  $ cd && cd Development
  $ svn checkout file:///home/marcob/workspace/svnrepo/test/trunk test
  A    test/index.php
  A    test/smarty
  A    test/stile.css
  Estratta revisione 1.
  $ ls
  adt-bundle-linux-x86_64-20130522  squirrel-sql-3.5.0  test

Update[modifica]

  |--------------|               |--------------|
  |  /var/www/   | <------------ |   svn repo   |
  |--------------|               |--------------|

Commit[modifica]

  |--------------|               |--------------|
  |  /var/www/   | ------------> |   svn repo   |
  |--------------|               |--------------|

Diff[modifica]

  |--------------|               |--------------|
  |  /var/www/   | >-----?-----< |   svn repo   |
  |--------------|               |--------------|

Log[modifica]

  marcob@js:~/Development/test$ svn log
  ------------------------------------------------------------------------
  r1 | marcob | 2013-10-31 10:27:11 +0100 (gio, 31 ott 2013) | 1 line
  
  initial import
  ------------------------------------------------------------------------

Ora faccio una minima modifica a index.php e poi vediamo come cambia:

Status[modifica]

  marcob@js:~/Development/test$ svn status
  M       index.php

Provo a vedere le differenze:

  marcob@js:~/Development/test$ svn diff
  Index: index.php
  ===================================================================
  --- index.php	(revisione 1)
  +++ index.php	(copia locale)
  @@ -0,0 +1,2 @@
  +<?php
  +?>

Esempio di un ciclo di lavoro completo[modifica]

mi sposto nella workspace di svn

  $ cd ~/workspace/php/marcob

creo una nuova directory in locale

  $ mkdir div_iov

la popolo

   $ cd div_iov
   $ mv /var/www/html/extra/div_iov/ .
   $ cd div_iov
   $ tar xf div_iov.LATEST.tgz
   $ rm div_iov.LATEST.tgz
   $ ll
   totale 116
   drwxrwxr-x  8 marcob marcob 4096 apr 10 11:42 ./
   drwxrwxr-x 10 marcob marcob 4096 apr 10 11:41 ../
   -rw-rw-r--  1 marcob marcob  448 apr 10 11:40 CHANGELOG.txt
   drwxrwxr-x  3 marcob marcob 4096 apr 10 11:40 filecomuni/
   -rw-rw-r--  1 marcob marcob 2879 apr 10 11:40 get_dati_dir.php
   -rw-rw-r--  1 marcob marcob  366 apr 10 11:40 get_dati.php
   -rw-rw-r--  1 marcob marcob 6772 apr 10 11:40 getpdf.php
   drwxrwxr-x  2 marcob marcob 4096 apr 10 11:40 images/
   drwxrwxr-x  2 marcob marcob 4096 apr 10 11:40 pdf/
   -rw-rw-r--  1 marcob marcob   67 apr 10 11:40 phpinfo.php
   drwxrwxr-x  2 marcob marcob 4096 apr 10 11:40 query/
   -rw-rw-r--  1 marcob marcob 2763 apr 10 11:40 relazione_dir.xml
   -rw-rw-r--  1 marcob marcob 2729 apr 10 11:40 relazione.xml
   drwxrwxr-x  2 marcob marcob 4096 apr 10 11:40 stampa/
   -rw-rw-r--  1 marcob marcob 8435 apr 10 11:40 stampa_dirAZ_PTA.xml
   -rw-rw-r--  1 marcob marcob 8414 apr 10 11:40 stampa_dirAZ.xml
   -rw-rw-r--  1 marcob marcob 2707 apr 10 11:40 stampa_dir.php
   -rw-rw-r--  1 marcob marcob 7590 apr 10 11:40 stampa_dir.xml
   -rw-rw-r--  1 marcob marcob 3255 apr 10 11:40 stampa.php
   -rw-rw-r--  1 marcob marcob 9837 apr 10 11:40 stampa.xml
   drwxrwxr-x  3 marcob marcob 4096 apr 10 11:40 xml/

torno ad un livello SOPRA la nuova cartella

   $ cd ..

aggiungo una nuova cartella div_iov ANCHE in remoto (e trasferisco contestualmente anche tutti i file che contiene)

   $ svn add div_iov
   ...
   A       xml/fpdf/templateULS.xml
   A       xml/template.xml
   A       xml/templateIOV.xml

torno DENTRO la directory

   $ cd div_iov

controllo lo stato

   $ svn status
   ...
   A       xml/fpdf/templateULS.xml
   A       xml/template.xml
   A       xml/templateIOV.xml

eseguo il commit

   $ svn commit -m "Importazione iniziale"
   ...
   Aggiungo       xml/fpdf/templateULS.xml
   Aggiungo       xml/template.xml
   Aggiungo       xml/templateIOV.xml
   Trasmissione dati ...............................................................................................
   Committed revision 7518.

FINE

Preferisco fare il commit da dentro la cartella in lavorazione.

compilazione del file CHANGELOG.txt[modifica]

Prendere l'id dell'ultimo commit eseguito dal sito:

ATTENZIONE viene visualizzato l'ultimo id consumato, quindi per il nuovo aggiungere +1

La struttura standard di una voce di versione è questa

   versione: git vx.y <--- questa è la versione in GIT
   autore: Nome Autore
   data: 05/05/2015
   Modifiche: 
       sunto conciso delle modifiche effettuate-. Se prima importazione scrivere: "Prima importazione"
   SVN: r7540 <--- questa è la versione SVN

Tendo ad usare un solo Versioning System (Git) ma alcuni clienti non lo usano, mi sono trovato questa modalità.

Se non è la prima importazione[modifica]

A differenza di Git, in SVN si può saltare il passaggio dell'ADD. Quindi

  • mettersi all'interno della cartella da aggiornare (ad esempio cd div_aop)
  • lanciare il commit
  $ svn commit -m "Cablatura logo nel template dirigenti e parametrizzazione per stampa manuale div vuoto"

Strutturare l'archivio per cartelle[modifica]

Ho la necessita di isolare in una cartella tutti i progetti Python. Quindi al livello più alto in cui si trova il mio repository creo la cartella python:

Operazioni nell'archivio locale[modifica]

  $ mkdir ~/workspace/python
  $ mkdir ~/workspace/python/proj1
  $ cp * ~/workspace/python/proj1

poi

 $ cd ~/workspace/

Operazioni in remoto[modifica]

  $ svn add python
  A         python
  A         python/proj1
  A  (bin)  python/proj1/documento_canali_proj1_python.odt
  A         python/proj1/CHANGELOG.txt
  A         python/proj1/proj1_invia.xml
  A         python/proj1/proj1_annulla.xml
  A         python/proj1/proj1_rettifica.xml

SVN ha così già creato anche tutta la gerarchia di sottocartelle, però d'ora in poi per committare le modifiche al singolo sottoprogetto dovrò sempre mettermi al livello python (non nella sottocartella con il codice modificato!)

  marcob@jsbach:~/workspace/python/proj1$ svn commit -m "Adeguamento client alla versione 3.3 del servizio"
  svn: E200009: Commit fallito (seguono dettagli):
  svn: E200009: '/home/marcob/workspace/python/proj1' is not known to exist in the repository and is not part of the commit, yet its child '/home/marcob/workspace/python/proj1' is part of the commit

Bisogna prima posizionarsi al livello inferiore a quello della creazione della cartella più alta:

  $ cd  ~/workspace/python/

e poi lanciare il commit

  $ svn commit -m "Adeguamento client alla versione 3.3 del servizio"
  Aggiungo       .
  Aggiungo       proj1
  Aggiungo       proj1/CHANGELOG.txt
  Aggiungo (bin) proj1/documento_canali_proj1_.odt
  Aggiungo       proj1/proj1_annulla.xml
  Aggiungo       proj1/proj1_invia.xml
  Aggiungo       proj1/proj1_rettifica.xml
  Trasmissione dati .....
  Committed revision 7612.