Gestire i sorgenti: Subversion e Trac
Note: Return to tutorial view.
Introduzione
Chi sviluppa software, per lavoro o per hobby, si è sicuramente scontrato con la questione della gestione dei sorgenti:
- come faccio a tornare indietro da una modifica ?
- come faccio a condividere il mio lavoro con più collaboratori ?
- come faccio ad avere un repository centralizzato dove conservare i sorgenti ?
La soluzione a tutti questi problemi è l'utilizzo di un software di gestione delle versioni.
Sono presenti moltissimi software di questo tipo. Nel mondo open source i più importanti sono:
- GIT - usato dagli sviluppatori del kernel di linux
- Bazaar - usato dalla Canonical per Ubuntu e altri progetti
- mercurial - usato da mozilla
- cvs - predecessore di svn ma ancora molto utilizzato
- subversion - attualmente il più usato
Questi software vengono spesso affiancati da altri per la gestione del progetto più in generale. Ad esempio: issue tracking (gestione dei bug e delle modifiche evolutive), documentazione di progetto, pubblicazione e condivisione.
Alcuni esempi sono:
In questo tutorial ho scelto di trattare Trac e Subversion.
Subversion: concetti e funzionalità
Subversion è stato sviluppato come successore di CVS con l'obiettivo di correggerne i problemi e ampliarne le possibilità.
I sorgenti vengono depositati su un archivio centralizzato (repository) accessibile da locale e via rete ( tramite i protocolli http/https, svnserve, svnserve con tunnel ssh ).
Il repository di SVN è simile ad una porzione di file-system con directory, file, subdirectory ecc. Oltre ai file e la struttura SVN ne memorizza anche le variazioni nel tempo. Ogni variazione viene identificata con un numero di revisione.
Tutte le modifiche al progetto vanno fatte sulla propria copia lavoro (detta working copy).
Le modifiche al repository sono atomiche: se le transazioni non vanno tutte a buon fine il repository non viene modificato
L'approccio di svn sulle modifiche ai sorgenti da parte di più persone contemporaneamente è di non bloccare l'utilizzo delle risorse ma di lasciarle modificare e, in seguito, di fondere le modifiche (ove possibile in modo automatico).
Due modifiche effettuate sullo stesso file si definiscono "conflitti".
Se le modifiche riguardano punti diversi del sorgente (in caso di file di testo) subversion è in grado di fonderle in modo automatico. Se sono nello stesso punto del codice vanno risolte da un programmatore.
E' possibile bloccare una risorsa. Ad esempio in caso di modifiche su file binari sarebbe impossibile risolvere il conflitto in modo automatico.
Un po' di terminologia
- trunk (tronco)
- ramo di sviluppo principale
- branches (rami)
- rami di sviluppo secondari
- tags
- ramo di sviluppo creato per un rilascio (da non modificare ulteriormente)
- working copy
- copia dei sorgenti in locale
- head
- ultima revisione del repository
- base
- ultima versione scaricata dal repository (dall'ultimo update)
Ciclo di lavoro normale
- Si recupera il sorgente con svn checkout
- Si fanno le modifiche
- Quando le modifiche sono complete si controlla il repository svn status/log/diff ed eventualmente ci si prepara alla soluzione di un conflitto
- Si aggiorna la propria working copy con le modifiche "committate" dagli altri e si risolvono i conflitti
- Si "committano" le modifiche con svn commit (con il commit è implicito anche un update della propria BASE)
- Si torna al punto 2
Operazioni comuni
Questa vuole essere solo una panoramica. Per una guida dettagliata del funzionamento e del client a riga di comando vi raccomando la documentazione ufficiale su http://svnbook.red-bean.com/.
- svn import
- primo import dei sorgenti nel repository
- svn checkout
- viene scaricato un ramo dal repository. La directory corrente diventa la working copy (nella directory nascosta .svn vengono scaricate le informazioni relative al repository e una copia dei sorgenti che, d'ora in avanti sarà la nostra base copy)
- svn update
- aggiorna la nostra working copy (e la versione BASE) con il repository. Eventuali conflitti vengono risolti automaticamente o segnalati
- svn commit
- le nostre modifiche vengono inviate al repository. L'operazione fallisce se la HEAD revision non è uguale alla BASE. Viene anche richiesta una descrizione delle modifiche che è buona norma scrivere.
- svn lock/unlock
- serve per bloccare/sbloccare un sorgente (per esempio un binario sul quale è necessario lavorare in una persona alla volta)
- svn resolved
- quando avviene un conflitto tra le nostre modifiche e la HEAD vengono creati tre file supplementari x.mine (la mia modifica), x.revisionebase (x nella revisione del mio ultimo update) x.revisionehead (nella revisione del repository). A questo punto la questione va sistemata a mano:
- se voglio buttare via la mia modifica faccio svn revert
- se voglio utilizzare la versione del repository, dopo aver modificato a mano il file faccio svn resolved
- svn revert
- Ritorna alla revisione BASE
- svn diff
- Mostra la differenza tra due revisioni (di default tra quella locale e la BASE)
- svn log
- mostra gli ultimi log
- svn status
- Mostra lo stato della working copy rispetto alla revisione BASE (se sono stati modificati, aggiunti o cancellati)
Con il flag -u mostra le modifiche rispetto alla HEAD
- svn add
- aggiunge un file o una directory al controllo di versione
- svn remove
- rimuove un file o una directory dal controllo di versione
- svn move
- muove un file o una directory
- svn copy
- utilizzato per creare branch e tag
- svn merge
- fonde le modifiche tra diversi branch
I branch ed i tag
L'utilizzo del comando svn copy ci consente di creare più versioni del nostro sorgente. Vediamo quali sono i casi d'uso più frequenti:
release branch
Si crea un ramo per gestire un rilascio. Su questo ramo verranno poi effettuate tutte le correzioni (non verranno però implementate nuove funzionalità). Eventuali correzioni dovrebbero poi essere riportate su altri rami di sviluppo utilizzando svn merge
feature branch
Si crea un ramo per sviluppare nuove funzionalità, per fare correzioni o rifattorizzazioni di una certa importanza. Una volta finita l'attività si importano le modifiche dove è opportuno (svn merge)
tag
Si crea un ramo in occasione di un rilascio. Questo Ramo viene conservato così com'è e non viene ulteriormente modificato. Serve a tenere lo storico dei rilasci.
Installazione
Su Ubuntu e Debian si può installare il client a riga di comando utilizzando:
sudo apt-get install subversion
Trac
Trac è una applicazione web che si integra con svn e aggiunge una serie di utili funzionalità:
Wiki integrato per scrivere documentazione al proprio progetto
Navigazione nel repository di subversion
Sistema di ticket per tenere traccia di segnalazioni di errori fino alla soluzione
Timeline per avere una vista storica del progetto in un singolo report
Roadmap per pianificare il progetto
Con Trac e subversion abbiamo a disposizione una soluzione completa con tutto il necessario per gestire un progetto. Ed è tutto open source !!!!
Subversion: installazione del server
Installazione di subversion
Affrontiamo ora l'installazione del server dei nostri sorgenti. Utilizzeremo subversion facendolo funzionare via rete con il protocollo http. In questo modo sarà possibile condividere il repository tra più postazioni. La procedura è stata testata con Debian e Ubuntu.
Come prima cosa installiamo subversion:
sudo apt-get install subversion
creiamo il gruppo subversion
sudo addgroup subversion
aggiungiamo l'utente www-data (l'utente di apache) e il tuo utente al gruppo subversion
sudo adduser www-data subversion sudo adduser mioutente subversion
Creiamo la directory che ospiterà i nostri repository:
sudo mkdir /home/svn cd /home/svn sudo mkdir myproject
settamo i permessi:
sudo chown -R www-data myproject sudo chgrp -R subversion myproject sudo chmod -R g+rws myproject
Creiamo il repository
sudo svnadmin create /home/svn/myproject
Da ora sarà possibile utilizzare il repository attraverso il file-system
Installazione di apache e dav_svn
Per poter condividere il repository via rete è necessario utilizzare apache ed il modulo dav_svn:
sudo apt-get install apache2 sudo apt-get install libapache2-svn sudo a2enmod dav_svn (opzionale)
E' anche necessario configurare il modulo. Aggiungiamo questa sezione su /etc/apache2/mods-available/dav_svn.conf:
<Location /svn/myproject> DAV svn SVNPath /home/svn/myproject AuthType Basic AuthName "myproject subversion repository" AuthUserFile /etc/subversion/passwd <LimitExcept GET PROPFIND OPTIONS REPORT> Require valid-user </LimitExcept> </Location>
Attenzione: per richiedere l'autorizzazione a tutte le connessioni al Server svn (SVN privato), bisogna rimuovere le linee <LimitExcept ...> e </LimitExcept>. Altrimenti verrà richiesta l'autenticazione solo per le modifiche al repository.
Per l'autenticazione è necessario creare il file /etc/subversion/passwd
sudo htpasswd -c /etc/subversion/passwd user_name sudo htpasswd /etc/subversion/passwd second_user_name . . .
Ora basta riavviare apache:
sudo /etc/init.d/apache2 restart
e sarà possibile lavorare sul nostro repository.
Ad esempio effettueremo il checkout con
svn co http://hostname/svn/myproject myproject --username user_name
Trac: installazione e configurazione
Installazione
Trac deve essere installato sullo stesso server dove è presente subversion (o almeno deve riuscire a vedere la directory /home/subversion).
Per la memorizzazione delle pagine utilizza sqlite di default ma può anche usare mysql o posgresgl.
Trac è basato su Python 2.5 quindi bisogna assicurarsi di averlo installato.
Per prima cosa installiamo il pacchetto per interfacciare Python con subversion:
sudo apt-get install python-subversion
Per l'installazione utilizzeremo easy_install. E' un sistema di installazione multipiattaforma per moduli python.
Installiamo quindi easy_install:
wget peak.telecommunity.com/dist/ez_setup.py python2.5 ez_setup.py
Installiamo Trac e Pygments (libreria per la colorazione della sintassi):
easy_install Trac easy_install Pygments
Configurazione
Per creare un nuovo progetto Trac eseguiamo:
trac-admin /percorso/progetto initenv
Con questo comando ci verranno richieste alcune domande:
- Nome del progetto - digitiamo il nome del nostro progetto
- Stringa di connessione al db - si può lasciare quella di default
- Tipo di repository - usiamo il default (SVN)
- path del repository - la directory del nostro repository subversion (si può mettere anche un ramo del repository). Nel nostro esempio scriviamo /home/subversion/myproject
A questo punto lanciando
tracd --port 8000 /percorso/progetto
verrà lanciato il web server di Trac che sarà visibile su http://nomepc:8000
NOTA BENE: tracd può essere configurato per utilizzare uno o più progetti differenti. Guardate le opzioni su http://trac.edgewall.org/wiki/TracStandalone
Configurare l'autenticazione
Trac può essere configurato per utilizzare le stesse utenze caricate per subversion. Basta lanciarlo con:
tracd --port 8000 /percorso/progetto --basic-auth=myproject,/etc/subversion/passwd,myproject
In questo caso abbiamo utilizzato l'autenticazione basic ma è possibile utilizzare anche l'autenticazione digest.
Per configurare i permessi è conveniente promuovere uno degli utenti ad amministratore con
trac-admin /percorso/progetto permission add nomeutente TRAC_ADMIN
Facendo log-in con questo utente sarà presente un bottone "admin" con il quale si avrà accesso alla configurazione dei permessi delle altre utenze.
Configurare il trac.ini
All'interno del progetto, nella directory conf si trova il file trac.ini. Al suo interno ci sono moltissime opzioni relative al progetto. Il reference si trova qui.
Far partire trac all'avvio
Per far partire trac si può usare questo comodo script di avvio trovato qui. Basta scrivere questo script su /etc/init.d/trac
#!/bin/sh
### BEGIN INIT INFO
# Provides: tracd
# Required-Start: networking
# Required-Stop: networking
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start the tracd standalone Trac web server.
### END INIT INFO
# (C) 2008 Guy Rutenberg <http://www.guyrutenberg.com>
## Options you should probably change ##
HOSTNAME=127.0.0.1 # to which hostname should we listen
# If you only want to serve one project keep this variable
# empty and set the PROJECT_ENV variable
ENV_PARENT_DIR=/home/guyru/trac.guyrutenberg.com
PROJECT_ENV=
PORT=8000
# add any additional options (such as authentication) here. If you only have one
# project you should probably add -s here
ADDITIONAL_OPTS=--basic-auth=myproject,/etc/subversion/passwd,myproject
## Options you should probably not change ##
DAEMON=/usr/bin/tracd
NAME=tracd
DESC="web server"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
SSD="/sbin/start-stop-daemon"
test -x $DAEMON || exit 1
set -e
. /lib/lsb/init-functions
DAEMON_OPTS="--daemonize --pidfile=$PIDFILE --port=$PORT --hostname=$HOSTNAME $ADDITIONAL_OPTS"
if [ -n "$ENV_PARENT_DIR" ]; then
DAEMON_OPTS="$DAEMON_OPTS --env-parent-dir=$ENV_PARENT_DIR"
else
DAEMON_OPTS="$DAEMON_OPTS $PROJECT_ENV"
fi
case "$1" in
start)
log_daemon_msg "Starting $DESC" $NAME
if ! $SSD --start --quiet\
--pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS ; then
log_end_msg 1
else
log_end_msg 0
fi
;;
stop)
log_daemon_msg "Stopping $DESC" $NAME
if $SSD --stop --retry 30\
--pidfile $PIDFILE ; then
rm -f $PIDFILE
log_end_msg 0
else
log_end_msg 1
fi
;;
restart|force-reload)
$0 stop
[ -r $PIDFILE ] && while pidof -x $NAME |\
grep -q `cat $PIDFILE 2>/dev/null` 2>/dev/null ; do sleep 1; done
$0 start
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
Con questo script si può pilotare Trac usando /etc/init.d/trac (start-stop-restart)
Oppure si può far avviare automaticanente all'avvio con
sudo update-rc.d trac defaults
Mettere Trac dietro apache
Per utilizzare Trac dietro apache basta creare il sito Trac su /etc/apache2/sites-available
<VirtualHost *> ServerAdmin you@yoursite.com ServerName www.yoursite.com ProxyPreserveHost On # this prevents the follow URL path from being proxied ProxyPass /svn ! # setup the proxy <Proxy *> Order allow,deny Allow from all </Proxy> ProxyPass / http://localhost:8000/ ProxyPassReverse / http://localhost:8000/ </VirtualHost>
poi si può lanciare
sudo a2ensite
e far ripartire apache con
sudo /etc/init.d/apache restart
Spero che questa guida sia utile. Happy hacking !!!
