CVS (Concurrent Versions System) è uno strumento open-source che consente di gestire e mantenere il codice sorgente di un progetto software. Di fatto CVS mette a disposizione del programmatore o di un gruppo di programmatori, un sistema di archiviazione del codice sorgente relativo alle procedure che costituiscono un progetto, tenendo traccia delle modifiche apportate dagli utenti alle diverse procedure inserite nell'archivio. Uno stesso archivio CVS può gestire più progetti software contemporaneamente.
I vantaggi nell'uso di un sistema come CVS sono notevoli, soprattutto quando il progetto viene sviluppato da più programmatori contemporaneamente o in un lasso di tempo prolungato e discontinuo:
Qualunque organizzazione di sviluppo informatico che intenda aderire ai più elementari principi di qualità nello sviluppo software dovrebbe adottare un prodotto di controllo delle versioni e della configurazione come CVS.
Nel gergo di CVS alcuni termini hanno un significato ben preciso che è opportuno conoscere:
La procedura di setup del prodotto CVS in ambiente MacOSX è descritta in modo molto semplice ed efficace sul sito della Apple dedicato agli sviluppatori (http://developer.apple.com/internet/opensource/cvsoverview.html). Dal momento che il prodotto per il sistema operativo MacOS X è ottenuto semplicemente ricompilando la versione originale di CVS come per qualunque altro sistema operativo UNIX-like, la procedura di setup è la stessa da seguire in altri ambienti analoghi, come Linux, Sun Solaris o altre versioni di UNIX.
Per l'installazione vera e propria del programma si rimanda alle istruzioni presenti in ogni distribuzione del pacchetto. Per la configurazione dell'ambiente di lavoro i passi essenziali sono invece descritti di seguito.
Deve essere creata una directory sotto a cui CVS memorizzerà tutti i file dei progetti e i file con le informazioni aggiuntive sulla "storia" dei sorgenti sottoiposti a controllo di versioning e configurazione. La directory deve risultare accessibile in lettura e scrittura ad un gruppo UNIX a cui appartengono gli utenti che sono abilitati ad operare sul repository.
Le variabili di ambiente CVSROOT ed eventualmente (se non si vuole usare l'editor di default vi) CVSEDITOR, devono essere impostate prima di iniziare ogni sessione di lavoro con CVS, dunque è opportuno modificare i file di configurazione della shell (~/.bashrc).
Prima di poter iniziare ad utilizzare il repository è necessario inizializzarlo con il comando "cvs init" con questo comando vengono create sotto a $CVSROOT le sottodirectory necessarie a gestire i progetti.
$ sudo -s # mkdir /usr/local/CVSrepository # chgrp cvs-users /usr/local/CVSrepository # ls -ld /usr/local/CVSrepository drwxr-xr-x 3 root cvs-users 58 Dec 9 21:30 /usr/local/CVSrepository # chmod g+w /usr/local/cvsrep # exit $ export CVSROOT=/usr/local/cvsrep $ export CVSEDITOR=emacs $ cvs init
Per creare un nuovo progetto sotto CVS è opportuno iniziare a costruire i file sorgente del progetto stesso, raccogliendoli sotto ad una directory principale del progetto (es.: ~/src/provacvs).
Per istanziare il nnuovo progetto nel repository CVS si deve usare il comando "cvs import" avendo stabilito come directory corrente la root directory del nuovo progetto:
$ cd ~/src/provacvs $ ls -l -rw-r--r-- 1 marco marco 232 Feb 19 18:11 index.html $ cvs import -m "Progetto di prova" progetto1 MLsoft start N progetto1/index.html No conflicts created by this import
È comodo denominare la directory di progetto con lo stesso nome del progetto stesso, dal momento che nelle successive estrazioni CVS scaricherà i file in una directory con lo stesso nome del progetto (creandola automaticamente se non dovesse esistere).
Per poter operare sui file che costituiscono un progetto presente nel repository CVS è necessario estrarli salvandoli in una directory locale con il comando "cvs checkout" Verranno estratti i file relativi al progetto e saranno salvati in una directory locale (creata come sottodirectory della directory corrente) identificata con il nome del progetto stesso. Nell'eseguire il checkout CVS non sovrappone i file che risultano essere più aggiornati nella copia locale rispetto alla versione presente nel repository.
$ cvs checkout progetto1 cvs checkout: Updating progetto1 U progetto1/index.html $ ls progetto1 CVS/ index.html
Per caricare sul repository le modifiche apportate localmente ad un file che fa parte di un progetto controllato da CVS si deve utilizzare il comando "cvs commit" specificando il nome del file che si intende caricare. Se non si spoecifica alcun file CVS verificherà la necessità di aggiornare sul repository tutti i file presenti nella directory corrente.
$ cvs commit -m "Aggiornamento del file index.html" index.html Checking in index.html; /usr/local/CVSrepository/progetto1/index.html,v <-- index.html new revision: 1.2; previous revision: 1.1 done
Per aggiungere un file al progetto è necessario utilizzare il comando "cvs add" In questo modo nei file di configurazione locali di CVS il nuovo file sarà contrassegnato come parte del progetto ed al successivo comando "cvs commit" sarà effettivamente caricato sul repository. È possibile aggiungere anche delle sottodirectory, ma in tal caso è necessario impartire il comando "cvs add" per ogni nuova directory aggiunta al progetto.
Per rimuovere un file dal repository si deve usare il comando "cvs remove" dopo aver fisicamente eliminato il file dalla directory di progetto locale. Il successivo comando "cvs commit" apporterà la modifica effettiva ai file custoditi sul repository.
$ rm pippo.html $ cvs remove pippo.html cvs remove: scheduling `pippo.html' for removal cvs remove: use 'cvs commit' to remove this file permanently $ cvs commit -m "Eliminato il file pippo.html" cvs commit: Examining .
Con il comando "cvs status" è possibile verificare lo stato di aggiornamento dei file appartenenti al progetto presenti nella directory corrente e in tutte le sottodirectory in essa contenute.
È possibile, ad esempio nel caso di un progetto web, che i file relativi ad un progetto siano suscettibili in quanto tali di pubblicazione nell'ambiente di esercizio; in tal caso i file presenti nel repository (ad esempio file in formato HTML, script CGI in Perl o pagine JSP, immagini grafiche in formato GIF o JPEG) possono essere copiati direttamente sul server di produzione senza la necessità di sottoporli a procedure di compilazione, come invece avverrebbe nel caso di un programma scritto in linguaggio C. In quest'ultimo caso infatti i file sorgente in linguaggio C non verrebbero distribuiti, ma ci si potrebbe limitare a distribuire i file compilati in formato eseguibile.
Il comando "cvs checkout" estrae dal repository anche le informazioni relative al versioning dei file. Per estrarre soltanto i file che compongono il progetto, senza altri file e directory aggiuntivi, si può usare il comando "cvs export":
$ cvs export -D "now" progetto1 cvs export: Updating progetto1 U progetto1/index.html cvs export: Updating progetto1/pippo U progetto1/pippo/index.html cvs export: Updating progetto1/pluto
È possibile effettuare le operazioni descritte in precedenza, operando su un repository CVS residente su un server collegato in rete con la postazione di lavoro locale. Per il trasferimento dei file è possibile utilizzare il protocollo proprietario di CVS, che però effettua lo scambio "in chiaro" dunque potenzialmente compromettendo la sicurezza del progetto, oppure effettuando un trasferimento mediante i protocolli ssh/scp.
È necessario che l'utente abbia un account utente sul server remoto. La variabile di ambiente CVSROOT può essere definita specificando la modalità di connessione, lo username e l'account utente utilizzato per effettuare il collegamento. Con la variabile CVS_RSH si può specificare il programma che deve essere utilizzato per effettuare lo scambio dei dati in modalità sicura (ad esempio con ssh).
marco@margot ~/src$ export CVSROOT=":ext:marco@henry:/usr/local/CVSrepository" marco@margot ~/src$ export CVS_RSH="ssh" marco@margot ~/src$ cvs checkout progetto1 Password: cvs checkout: Updating progetto1 U progetto1/index.html U progetto1/pluto.html cvs checkout: Updating progetto1/pippo U progetto1/pippo/index.html cvs checkout: Updating progetto1/pluto marco@margot ~/src$ vi pluto.html marco@margot ~/src$ cvs commit -m "Modifica dei file effettuata su margot" cvs commit: Examining . cvs commit: Examining pippo cvs commit: Examining pluto Password: Checking in pluto.html; /usr/local/CVSrepository/progetto1/pluto.html,v <-- pluto.html new revision: 1.2; previous revision: 1.1 done
Naturalmente per ogni operazione effettuata sul server remoto attraverso il protocollo sicuro ssh, viene richiesta la password dell'utente per l'accesso al server. In questo caso la macchina locale su cui opera l'utente si chiama "margot" mentre "henry" è il server remoto su cui è attivo il server CVS.