[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico] [volume] [parte]


Capitolo 172.   CVS: introduzione

CVS è letteralmente un sistema di controllo delle versioni di un progetto legato alla produzione e alla modifica di file. In pratica, permette a un gruppo di persone di lavorare simultaneamente sullo stesso gruppo di file (generalmente si tratta di sorgenti di un programma), mantenendo il controllo dell'evoluzione delle modifiche che vengono apportate. Per attuare questo obiettivo, il sistema CVS mantiene un deposito centrale (repository) dal quale i collaboratori di un progetto possono ottenere una copia di lavoro. I collaboratori modificano i file della loro copia di lavoro e sottopongono le loro modifiche al sistema CVS che le integra nel deposito.

Il compito di un sistema CVS non si limita a questo; per esempio è sempre possibile ricostruire la storia delle modifiche apportate a un gruppo di file, oltre a essere anche possibile ottenere una copia che faccia riferimento a una versione passata di quel lavoro.

172.1   Logica di funzionamento

Il sistema CVS si basa su un deposito, o repository, contenente le informazioni sullo svolgimento di uno o più progetti gestiti da uno o più gruppi di persone. Questo deposito è costituito evidentemente da una directory che si sviluppa in una gerarchia più o meno complessa, in base alla struttura di ciò che si vuole amministrare. Parallelamente, ogni collaboratore deve riprodurre un'immagine della parte di progetto di suo interesse e sulla quale intende intervenire attraverso delle modifiche; anche questa immagine personale viene inserita in una directory a cui quell'utente può avere accesso.

Il deposito CVS e la copia di un collaboratore possono risiedere nello stesso file system, eventualmente esteso attraverso la rete con il protocollo NFS, oppure possono trovarsi all'interno di nodi di rete differenti e in tal caso la gestione del deposito deve avvenire attraverso un servente CVS.

Nella parte iniziale di questo capitolo verrà affrontato il problema della gestione del sistema CVS immaginando che il deposito e le copie dei collaboratori risiedano sempre nello stesso file system.

172.1.1   Deposito CVS

Come accennato, il deposito CVS è una directory che si articola in qualche modo. La sua posizione iniziale nel file system è la radice del deposito e normalmente si utilizza la variabile di ambiente CVSROOT per indicarla in modo predefinito ai comandi di CVS. All'interno dello stesso file system possono essere ospitati diversi depositi CVS in posizioni differenti. La variabile CVSROOT va impostata da ogni collaboratore in modo da puntare al deposito contenente i file del progetto a cui si intende collaborare.

All'interno di un deposito si possono articolare diverse directory, con la loro struttura, riferite a uno stesso progetto o a progetti differenti, che possono articolarsi in sottoprogetti a seconda delle necessità. Nella terminologia di CVS, questi progetti sono dei moduli. La figura 172.1 mostra un esempio di come potrebbe essere collocata e strutturata la gerarchia di un deposito; in particolare, tutti i nomi che si vedono sono delle directory.

Figura 172.1. Struttura di un deposito CVS.

/var/
 |
 |-- radice-cvs/
 |    |
 :    |-- CVSROOT/
      |         (directory amministrativa)
      |
      |-- esercizi/
      |    |    (modulo «esercizi») 
      :    |
           |-- basic/
           |    (modulo «esercizi/basic»)
           |
           |-- c/
           |    (modulo «esercizi/c»)
           |
           |-- pascal/
           |    (modulo «esercizi/pascal»)
           :

È importante osservare subito la presenza della directory CVSROOT/. Si tratta di un contenitore di file amministrativi gestiti dal sistema CVS; come si vede, discende immediatamente dalla radice del deposito che nell'esempio mostrato nella figura corrisponde al percorso /var/radice-cvs/. Purtroppo, la variabile di ambiente che punta al percorso della radice ha lo stesso nome, CVSROOT, cosa che può creare un po' di confusione inizialmente.

172.1.2   Copia personale dei collaboratori

Il collaboratore che intende partecipare allo sviluppo di un modulo (o di un sottomodulo), riproduce una copia di questo a partire da una sua directory di lavoro. La figura 172.2 mostra il caso dell'utente tizio che possiede una copia del modulo esercizi/pascal (e non degli altri) a partire dalla propria directory personale.

Figura 172.2. Esempio di struttura della copia di un modulo appartenente a un collaboratore.

~tizio/
 |
 |-- esercizi/
 |    |
 :    |-- CVS/
      |     (directory amministrativa)
      |
      |-- pascal/
      |    |
      :    |-- CVS/
           |    (directory amministrativa)
           |
           |-- BSort.pas
           |-- BSort2.pas
           :    (sorgenti pascal da sviluppare)
           :

Se invece il collaboratore partecipasse a tutto il modulo esercizi, la sua struttura sarebbe completata degli altri sottomoduli, compresi i file contenuti direttamente dalla directory esercizi/, ammesso che ce ne siano.

172.1.3   Fasi essenziali del lavoro di gruppo

Quando un collaboratore ha riprodotto la propria copia di lavoro del modulo di suo interesse, può apportare le modifiche che ritiene opportune nei file e quindi dovrebbe fare in modo di aggiornare anche il deposito generale. A questo proposito conviene distinguere le fasi seguenti:

  1. modifica dei file;

  2. aggiornamento della copia locale;

  3. sistemazione dei conflitti;

  4. invio delle modifiche al deposito.

Il senso di questi passaggi è abbastanza semplice: il collaboratore che modifica qualcosa, prima di sottoporre le modifiche al sistema di gestione del deposito, deve verificare che nel frattempo qualcun altro non sia intervenuto negli stessi file; se CVS riesce a sistemare le cose, bene, altrimenti occorre rimediare manualmente ai conflitti che si sono creati.

Per tenere traccia degli interventi dei singoli collaboratori, CVS gestisce un numero di revisione indipendente per ogni file amministrato.

172.1.4   Revisione

Un progetto, come per esempio la realizzazione di un programma, può essere composto da diversi file. Una volta giunti a uno stadio conclusivo del progetto, gli si può attribuire un numero di versione, come si è abituati di solito. CVS, per tenere traccia delle variazioni apportate ai singoli file, abbina loro un numero di revisione che non ha nulla a che fare con il numero di versione del progetto, tanto che generalmente viene ignorato. La numerazione della revisione è articolata in modo piuttosto complesso, come 1.1, 1.2,... o anche 1.1.1.1, 1.1.1.2,... oppure anche a livelli ancora più dettagliati.

172.2   Creazione e gestione di un progetto in pratica

Data la complessità del meccanismo di gestione del sistema CVS, conviene vedere subito il procedimento per la creazione di un deposito CVS e l'interazione con questo. Si vuole creare un deposito contenente una serie di esempi di programmazione di vari linguaggi, da usare come soluzione per degli esercizi da dare agli studenti di un corso di studio. Alcuni professori lavorano assieme per modificare o estendere il gruppo di esercizi; in particolare, gli utenti tizio e caio lavorano assieme per lo sviluppo degli esempi e delle soluzioni in linguaggio C. È chiaro che si vuole riprendere quanto mostrato già nelle figure 172.1 e 172.2.

172.2.1   Collocazione e creazione del deposito

La prima cosa da fare è decidere dove debba essere collocato il deposito CVS per la gestione di questi esercizi. Per la precisione occorre stabilire la posizione della radice del deposito. Il percorso di questa deve poi essere indicato nella variabile di ambiente CVSROOT, in modo da facilitare la composizione dei comandi CVS. Per comodità si suppone che sia l'utente root a creare il deposito; questo verrà messo a partire dalla directory /var/radice-cvs/.

CVSROOT=/var/radice-cvs

export CVSROOT

Dopo aver predisposto la variabile di ambiente, l'utente root può creare il deposito con il comando seguente:

cvs init

Si otterrà la creazione della directory /var/radice-cvs/ e di /var/radice-cvs/CVSROOT/, all'interno della quale si troveranno collocati già una serie di file amministrativi.

172.2.2   Gruppo di lavoro e sistemazione dei permessi

Se è l'utente root che crea il deposito, le directory e i file relativi apparterranno a lui e al suo gruppo. Gli utenti che intendono collaborare ai progetti da gestire all'interno di questo deposito devono avere i permessi necessari a creare e modificare alcuni file amministrativi contenuti all'interno di /var/radice-cvs/CVSROOT/, inoltre dovranno poter alterare i file delle altre directory.

La regolazione dei permessi di un deposito CVS è un problema delicato e poco documentato. Probabilmente è conveniente la creazione di un gruppo apposito; in questo caso si opta per il nome esercizi. Per la creazione di questo si può intervenire manualmente nel file /etc/group, oppure si possono utilizzare altri strumenti, a seconda di come è organizzato il proprio sistema.

groupadd esercizi

Successivamente occorre aggregare al gruppo gli utenti che partecipano allo sviluppo del progetto. Di solito si interviene manualmente nel file, come nell'esempio seguente.

esercizi:x:901:tizio,caio

Infine, occorre cominciare a modificare la proprietà e i permessi delle directory e dei file amministrativi del deposito appena creato.

chgrp -R esercizi /var/radice-cvs

Se si ritiene che gli utenti estranei al gruppo non debbano accedere in alcun modo al deposito, si possono togliere tutti i permessi per gli utenti che non siano né i proprietari, né appartengano al gruppo:

chmod -R o-rwx /var/radice-cvs

172.2.3   Ambiente dei collaboratori

Così come l'utente che crea il deposito, anche gli altri utenti che collaborano a un progetto devono predisporre la variabile di ambiente CVSROOT, in modo che punti alla radice del deposito con il quale intendono operare. L'esempio seguente riguarda tizio.

tizio:~$ CVSROOT=/var/radice-cvs

tizio:~$ export CVSROOT

Se ci si dimentica di farlo, quando si utilizza un comando di CVS tra quelli che ne hanno bisogno, si ottiene una segnalazione di errore del tipo:

No CVSROOT specified!  Please use the `-d' option
or set the CVSROOT environment variable.

che invita a predisporre tale variabile, oppure a utilizzare l'opzione -d che verrà descritta in seguito.

172.2.4   Inserimento dei moduli nel deposito

Per cominciare la gestione di un progetto attraverso CVS, si parte generalmente da qualcosa che è già stato iniziato in qualche modo, senza CVS, inserendolo in un deposito già esistente. Questo lo fa uno dei collaboratori che ha i permessi per modificare la directory radice del deposito. La directory corrente nel momento in cui si esegue l'operazione, detta di «importazione», deve essere quella a partire dalla quale si articolano i file e le directory del materiale da inserire nel deposito.

tizio:~$ cd /tmp/eserciziario

Si suppone che la directory /tmp/eserciziario/ contenga le sottodirectory degli esempi di programmazione di alcuni linguaggi.

tizio:/tmp/eserciziario$ cvs import <-'
`->-m "Importazione dei sorgenti iniziali" <-'
`->esercizi esercitazioni inizio

Il comando di importazione è un po' complesso:

Il comando dovrebbe generare una serie di messaggi che confermano l'importazione. Le voci che appaiono precedute da una lettera N confermano l'inserimento del file corrispondente (la lettera L si riferisce a collegamenti simbolici, che comunque vengono perduti).

cvs import: Importing /var/radice-cvs//esercizi/c
N esercizi/c/dimensione_variabili.c
N esercizi/c/somma.c
N esercizi/c/somma2.c
N esercizi/c/bsort.c
    ...
cvs import: Importing /var/radice-cvs//esercizi/basic
N esercizi/basic/somma.bas
L esercizi/basic/somma.TEXT
N esercizi/basic/moltiplica.bas
L esercizi/basic/moltiplica.TEXT
N esercizi/basic/dividi.bas
    ...
cvs import: Importing /var/radice-cvs//esercizi/pascal
N esercizi/pascal/CiaoMondo.pas
N esercizi/pascal/Nulla.pas
N esercizi/pascal/Dividi.pas
N esercizi/pascal/Exp.pas
    ...

No conflicts created by this import

Se non dovesse essere fornita la descrizione dell'operazione attraverso l'opzione -m, verrebbe avviato un programma per la modifica di file di testo, generalmente VI, con il quale si verrebbe costretti a fornire tale indicazione.

CVS: ----------------------------------------------------------------------
CVS: Enter Log.  Lines beginning with `CVS:' are removed automatically
CVS:
CVS: ----------------------------------------------------------------------
Importazione dei sorgenti iniziali

Il risultato dell'importazione è la creazione della directory /var/radice-cvs/esercizi/ e di altre sottodirectory in base a quanto contenuto nella directory corrente nel momento dell'avvio del comando. Volendo dare un'occhiata, si può osservare che i file non sono copiati semplicemente: il contenuto e il loro nome viene modificato. Per esempio, se all'inizio c'era il file /tmp/eserciziario/c/fatt.c, nel deposito si trova il file /var/radice-cvs/esercizi/c/fatt.c,v, che contiene tutte le informazioni sul suo stato iniziale. Quello che segue è l'esempio di ciò che potrebbe contenere.


head     1.1;
branch   1.1.1;
access   ;
symbols  inizio:1.1.1.1 esercitazioni:1.1.1;
locks    ; strict;
comment  @ * @;


1.1
date     99.01.27.19.38.56;  author tizio;  state Exp;
branches 1.1.1.1;
next     ;

1.1.1.1
date     99.01.27.19.38.56;  author tizio;  state Exp;
branches ;
next     ;


desc
@@



1.1
log
@Initial revision
@
text
@/* ================================================================= */
/* fatt <x>                                                          */
/* Fattoriale.                                                       */
/* ================================================================= */

#include <stdio.h>

/* ================================================================= */
/* fatt ( <x> )                                                      */
/* ----------------------------------------------------------------- */
int fatt( int x ) {

    int i = ( x - 1 );

    while ( i > 0 ) {

        x = x * i;
        i--;
    }

    return x;
}

/* ================================================================= */
/* Inizio del programma.                                             */
/* ----------------------------------------------------------------- */
int main( int argc, char *argv[] ) {

    int x;
    int z;

    sscanf( argv[1], "%d", &x );

    z = fatt( x );

    printf( "%d! = %d\n", x, z );
}

@


1.1.1.1
log
@Importazione dei sorgenti iniziali
@
text
@@

172.2.5   Permessi dei moduli

Le directory di ciò che è stato inserito nel deposito sono dei moduli, secondo la terminologia di CVS. Quindi, esercizi/ è un modulo, ma anche esercizi/c/ è un modulo, benché di livello inferiore. Nel momento in cui vengono create le directory, con i file relativi, questi acquisiscono la proprietà dell'utente che ha eseguito il comando di importazione; se si vuole che i dati siano accessibili anche ad altri utenti collaboratori, occorre modificare qualcosa. Per esempio si può attribuire a questi file e directory il gruppo definito inizialmente per l'accesso alla directory amministrativa CVSROOT/, oppure si può scindere la gestione del progetto in modo da individuare dei sottogruppi competenti per i sottomoduli rispettivi (il sottogruppo che si occupa del linguaggio C, quello che segue il Pascal e quello che segue il Basic). Per semplificare le cose si concede a tutti i collaboratori di agire su tutto il modulo esercizi/.

chgrp -R esercizi /var/radice-cvs/esercizi

Volendo, si può anche impedire agli utenti estranei di accedere in qualunque modo a questi file:

chmod -R o-rwx /var/radice-cvs/esercizi

Dato questo tipo di impostazione, prima di iniziare a fare qualunque cosa, gli utenti che collaborano alla gestione di questi moduli dovrebbero inserirsi nel gruppo stabilito:

newgrp esercizi

172.2.6   Prelievo della copia di lavoro

L'utente tizio, quando decide di mettersi a lavorare sugli esercizi in linguaggio C può farsi una copia locale del modulo esercizi/c/, lasciando stare tutto il resto.

cd

La prima cosa che deve fare è spostarsi nella directory a partire dalla quale vuole copiare ciò che gli serve; per esempio potrebbe essere la sua directory personale, come mostrato.

tizio:~$ cvs checkout esercizi/c

Con questo comando richiede di prelevare il modulo esercizi/c/, che gli viene inserito a partire dalla directory corrente. Da questo momento, tizio può cominciare a modificare i file.

cvs checkout: Updating esercizi/c
U esercizi/c/bsort.c
U esercizi/c/bsort2.c
    ...
U esercizi/c/fatt.c
U esercizi/c/fatt2.c
    ...

I file trasferiti con successo vengono indicati con la lettera U (update) all'inizio della voce corrispondente.

Nelle sezioni seguenti si suppone che anche caio faccia la stessa cosa, mettendosi a lavorare anche lui sui sorgenti in linguaggio C.

172.2.7   Aggiornamento e invio delle modifiche nel deposito

Supponiamo che sia tizio che caio si mettano a lavorare sullo stesso file: esercizi/c/fatt.c.


/* ================================================================= */
/* fatt <x>                                                          */
/* Fattoriale.                                                       */
/* ================================================================= */

#include <stdio.h>

/* ================================================================= */
/* fatt ( <x> )                                                      */
/* ----------------------------------------------------------------- */
int fatt( int x ) {

    int i = ( x - 1 );

    while ( i > 0 ) {

        x = x * i;
        i--;
    }

    return x;
}

/* ================================================================= */
/* Inizio del programma.                                             */
/* ----------------------------------------------------------------- */
int main( int argc, char *argv[] ) {

    int x;
    int z;

    sscanf( argv[1], "%d", &x );

    z = fatt( x );

    printf( "%d! = %d\n", x, z );
}

L'utente caio, per conto suo, ritiene che il file ha troppi commenti e decide di togliere un po' di cornicette che secondo lui sono superflue. In qualche modo invia l'aggiornamento al deposito CVS, mentre tizio modifica l'istruzione di visualizzazione del risultato nella sua copia:


    printf( "%d! = %d\n", x, z );

diventa


    printf( "Il fattoriale di %d e' %d\n", x, z );

L'utente tizio, prima di inviare il suo aggiornamento al deposito, cerca di allineare la sua copia del modulo esercizi/c/ con le modifiche eventuali che fossero state apportate da altri (guarda caso caio ha proprio modificato lo stesso file).

tizio:~$ cvs update esercizi/c

cvs update: Updating esercizi/c
RCS file: /var/radice-cvs/esercizi/c/fatt.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
Merging differences between 1.1.1.1 and 1.2 into fatt.c
M esercizi/c/fatt.c

In qualche modo, il sistema CVS riesce ad aggiornare il file esercizi/c/fatt.c senza perdere le modifiche fatte da tizio, che così può inviare le sue modifiche al deposito.

tizio:~$ cvs commit <-'
`->-m "Modifica della visualizzazione del risultato" <-'
`->esercizi/c/fatt.c

Checking in esercizi/c/fatt.c;
/var/radice-cvs/esercizi/c/fatt.c,v  <--  fatt.c
new revision: 1.3; previous revision: 1.2
done

Così, alla fine, il file esercizi/c/fatt.c giunge alla sua revisione 1.3 (la 1.2 era quella delle modifiche fatte da caio), con il contenuto che si può vedere di seguito:


/* fatt <x>                                                          */
/* Fattoriale.                                                       */

#include <stdio.h>

/* fatt ( <x> )                                                      */
int fatt( int x ) {

    int i = ( x - 1 );

    while ( i > 0 ) {

        x = x * i;
        i--;
    }

    return x;
}

/* Inizio del programma.                                             */
int main( int argc, char *argv[] ) {

    int x;
    int z;

    sscanf( argv[1], "%d", &x );

    z = fatt( x );

    printf( "Il fattoriale di %d e' %d\n", x, z );
}

Volendo si può anche verificare la situazione del file attraverso il comando cvs status.

tizio:~$ cvs status esercizi/c/fatt.c

===================================================================
File: fatt.c            Status: Up-to-date

   Working revision:    1.3     Wed Jan 27 21:09:43 1999
   Repository revision: 1.3     /var/radice-cvs/esercizi/c/fatt.c,v
   Sticky Tag:          (none)
   Sticky Date:         (none)
   Sticky Options:      (none)

172.2.8   Conflitti tra le modifiche dei collaboratori

CVS fa quello che può nel cercare di mettere assieme le modifiche apportate da altri all'interno di file in corso di modifica da parte di un certo utente. A parte le abilità di CVS, occorre vedere poi se queste modifiche possono realmente convivere assieme. Ci sono comunque situazioni in cui CVS non sa cosa fare. A questo proposito, si suppone che gli utenti tizio e caio si mettano a lavorare sulla stessa riga del sorgente esercizi/c/fatt.c, quella dell'istruzione printf. caio vuole l'istruzione


    printf( "fatt(%d) = %d\n", x, z );

mentre tizio ci ripensa e la modifica ancora in


    printf( "factorial(%d) = %d\n", x, z );

Ancora una volta, caio è più rapido e riesce ad aggiornare il deposito. Di conseguenza tizio deve aggiornare la propria copia prima di trasmettere la sua modifica.

tizio:~$ cvs update esercizi/c

cvs update: Updating esercizi/c
RCS file: /var/radice-cvs/esercizi/c/fatt.c,v
retrieving revision 1.3
retrieving revision 1.4
Merging differences between 1.3 and 1.4 into fatt.c
rcsmerge: warning: conflicts during merge
cvs update: conflicts found in esercizi/c/fatt.c
C esercizi/c/fatt.c

Come si vede dal messaggio ottenuto, la fusione dell'aggiornamento crea dei problemi e occorre intervenire a mano nel file. Nella parte finale del file si osservano le righe evidenziate dai simboli <<<<<<< e >>>>>>>.


    ...
/* Inizio del programma.                                             */
int main( int argc, char *argv[] ) {

    int x;
    int z;

    sscanf( argv[1], "%d", &x );

    z = fatt( x );

<<<<<<< fatt.c
    printf( "factorial(%d) = %d\n", x, z );
=======
    printf( "fatt(%d) = %d\n", x, z );
>>>>>>> 1.4
}

Il significato si intuisce: per raggiungere la revisione 1.4 occorrerebbe sostituire la riga


    printf( "factorial(%d) = %d\n", x, z );

scritta da tizio, con la riga


    printf( "fatt(%d) = %d\n", x, z );

che è contenuta nella revisione pubblicata attualmente nel deposito. tizio deve scegliere, modificando il file in un modo o nell'altro.

Ogni volta che si esegue un aggiornamento e questo va ad alterare dei file che erano in corso di modifica da parte dell'utente, CVS crea una copia di sicurezza il cui nome inizia con il prefisso .# e termina con il numero del rilascio. Avendo subito per due volte un aggiornamento del genere, tizio ne ha due, riferiti entrambi al solito esercizi/c/fatt.c. Si tratta di: .#fatt.c.1.1.1.1 e .#fatt.c.1.3.

172.2.9   Situazione di un file

Si è accennato alla possibilità di verificare la situazione di un file; se tizio richiede la situazione del file esercizi/c/fatt.c dopo quanto è stato descritto nella sezione precedente, gli viene ricordato che il file deve essere sistemato.

tizio:~$ cvs status esercizi/c/fatt.c

===================================================================
File: fatt.c            Status: File had conflicts on merge

   Working revision:    1.4     Result of merge
   Repository revision: 1.4     /var/radice-cvs/esercizi/c/fatt.c,v
   Sticky Tag:          (none)
   Sticky Date:         (none)
   Sticky Options:      (none)

Segue l'elenco delle definizioni con cui può essere descritto lo stato di un file:

Up-to-date il file è allineato all'ultima revisione presente nel deposito;
Locally Modified il file è stato modificato localmente e non ancora inviato al deposito;
Locally Added il file è stato aggiunto localmente ma non è ancora stato trasmesso al deposito;
Locally Removed il file è stato eliminato localmente ma non è ancora stato comunicato al deposito;
Needs Checkout nel deposito è presente una revisione più recente per la quale è richiesto un prelievo (attraverso cvs update);
Needing Patch nel deposito è presente una revisione più recente;
Needs Merge nel deposito è presente una revisione più recente, mentre anche la copia locale è stata modificata nel frattempo;
File had conflicts on merge è stata fatta una fusione tra un aggiornamento proveniente dal deposito e un file che nel frattempo era già stato modificato localmente in modo incompatibile;
Unknown quando CVS non sa nulla sul file in questione.

Supponendo che tizio modifichi il file in modo da accettare le modifiche apportate da caio, la sua copia diventa istantaneamente allineata alla revisione ufficiale contenuta nel deposito.

tizio:~$ cvs status esercizi/c/fatt.c

===================================================================
File: fatt.c            Status: Up-to-date

   Working revision:    1.4     Result of merge
   Repository revision: 1.4     /var/radice-cvs/esercizi/c/fatt.c,v
   Sticky Tag:          (none)
   Sticky Date:         (none)
   Sticky Options:      (none)

172.2.10   Aggiunta ed eliminazione di file

L'aggiunta e l'eliminazione di un file all'interno di una copia locale, non hanno effetto nel deposito CVS se non vengono usati i comandi appositi: cvs add e cvs remove. Supponendo che l'utente tizio voglia togliere di mezzo il file esercizi/c/fatt2.c, dovrebbe prima eliminarlo dalla sua copia di lavoro,

tizio:~$ rm esercizi/c/fatt2.c

tizio:~$ cvs remove esercizi/c/fatt2.c

cvs remove: scheduling `esercizi/c/fatt2.c' for removal
cvs remove: use 'cvs commit' to remove this file permanently

e quindi dovrebbe estendere la sua azione al deposito CVS:

tizio:~$ cvs commit -m "Eliminato fatt2.c che mi sta antipatico" <-'
`->esercizi/c/fatt2.c

Removing esercizi/c/fatt2.c;
/var/radice-cvs/esercizi/c/fatt2.c,v  <--  fatt2.c
new revision: delete; previous revision: 1.1.1.1
done

L'eliminazione del file nel deposito si traduce nella creazione, se necessario, della directory Attic/ (la «soffitta») e nel trasferimento del vecchio file fatt2.c,v al suo interno. In questo modo è sempre possibile ottenere una vecchia revisione di questo file, anche se attualmente non viene più usato.

L'inserimento di un nuovo file procede in modo simile. Supponendo che tizio abbia aggiunto il file esercizi/c/fattoriale.c nella sua copia locale, dovrebbe agire utilizzando i comandi seguenti:

tizio:~$ cvs add esercizi/c/fattoriale.c

cvs add: scheduling file `esercizi/c/fattoriale.c' for addition
cvs add: use 'cvs commit' to add this file permanently

tizio:~$ cvs commit -m "Aggiunto fattoriale.c" esercizi/c/fattoriale.c

RCS file: /var/radice-cvs/esercizi/c/fattoriale.c,v
done
Checking in esercizi/c/fattoriale.c;
/var/radice-cvs/esercizi/c/fattoriale.c,v  <--  fattoriale.c
initial revision: 1.1
done

172.2.11   Evoluzione di un file

In precedenza si è mostrato che il comando cvs status permette di conoscere lo stato attuale di un certo file. Il comando cvs log permette di conoscere la sequenza degli interventi attuati su un certo file. In questa serie di esempi, il file esercizi/c/fatt.c è stato rimaneggiato più volte:

tizio:~$ cvs log esercizi/c/fatt.c

RCS file: /var/radice-cvs/esercizi/c/fatt.c,v
Working file: esercizi/c/fatt.c
head: 1.4
branch:
locks: strict
access list:
symbolic names:
        inizio: 1.1.1.1
        esercitazioni: 1.1.1
keyword substitution: kv
total revisions: 5;     selected revisions: 5
description:
----------------------------
revision 1.4
date: 1999/01/27 21:31:30;  author: caio;  state: Exp;  lines: +1 -1
Non mi piace il modo di mostrare il risultato
----------------------------
revision 1.3
date: 1999/01/27 21:13:32;  author: tizio;  state: Exp;  lines: +1 -1
Modifica della visualizzazione del risultato
----------------------------
revision 1.2
date: 1999/01/27 21:01:28;  author: caio;  state: Exp;  lines: +0 -7
Eliminati un po' di cornici ai commenti
----------------------------
revision 1.1
date: 1999/01/27 19:38:56;  author: tizio;  state: Exp;
branches:  1.1.1;
Initial revision
----------------------------
revision 1.1.1.1
date: 1999/01/27 19:38:56;  author: tizio;  state: Exp;  lines: +0 -0
Importazione dei sorgenti iniziali
=============================================================================

Anche i file eliminati possono essere analizzati in questo modo:

tizio:~$ cvs log esercizi/c/fatt2.c

RCS file: /var/radice-cvs/esercizi/c/Attic/fatt2.c,v
Working file: esercizi/c/fatt2.c
head: 1.2
branch:
locks: strict
access list:
symbolic names:
        inizio: 1.1.1.1
        esercitazioni: 1.1.1
keyword substitution: kv
total revisions: 3;     selected revisions: 3
description:
----------------------------
revision 1.2
date: 1999/01/28 07:09:52;  author: tizio;  state: dead;  lines: +0 -0
Eliminato fatt2.c che mi sta antipatico
----------------------------
revision 1.1
date: 1999/01/27 19:38:56;  author: tizio;  state: Exp;
branches:  1.1.1;
Initial revision
----------------------------
revision 1.1.1.1
date: 1999/01/27 19:38:56;  author: tizio;  state: Exp;  lines: +0 -0
Importazione dei sorgenti iniziali
=============================================================================

Infine, anche il file esercizi/c/fattoriale.c creato da tizio, può essere interessante:

tizio:~$ cvs log esercizi/c/fattoriale.c

RCS file: /var/radice-cvs/esercizi/c/fattoriale.c,v
Working file: esercizi/c/fattoriale.c
head: 1.1
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 1;     selected revisions: 1
description:
----------------------------
revision 1.1
date: 1999/01/28 07:20:56;  author: tizio;  state: Exp;
Aggiunto fattoriale.c
=============================================================================

172.2.12   Differenza tra la copia locale e il deposito

Quando si modifica un file nella propria copia locale, prima di inviarlo al deposito conviene verificare il suo stato e se necessario aggiornarlo alla revisione presente nel deposito. Prima di tale aggiornamento è possibile verificare quali siano le differenze tra i due file con il comando cvs diff. Supponendo che tizio abbia modificato il commento iniziale del file esercizi/c/fattoriale.c (che prima era errato),

tizio:~$ cvs diff esercizi/c/fattoriale.c

si potrebbe ottenere il risultato seguente:

Index: esercizi/c/fattoriale.c
===================================================================
RCS file: /var/radice-cvs/esercizi/c/fattoriale.c,v
retrieving revision 1.1
diff -r1.1 fattoriale.c
1c1
< /* fatt <x>                                                        */
---
> /* fattoriale <x>                                                  */

172.2.13   Etichettare un modulo intero

Come si è visto, ogni file viene seguito da CVS con una propria numerazione di revisione. Quando è necessario etichettare in qualche modo un gruppo di file per poterli identificare in seguito, ognuno alla revisione in cui si trovava, si utilizza il comando cvs tag oppure cvs rtag. Per esempio, l'utente tizio potrebbe decidere di attribuire il nome c-1 alla situazione attuale del modulo esercizi/c/.

tizio:~$ cvs tag c-1 esercizi/c/

cvs tag: Tagging esercizi/c
T esercizi/c/bsort.c
T esercizi/c/bsort2.c
    ...
T esercizi/c/fatt.c
T esercizi/c/fattoriale.c
    ...

Il responso che si ottiene è abbastanza chiaro: vengono elencati tutti i file a cui è stata attribuita l'etichetta c-1. (la lettera T sta per tag).

Il fatto di avere etichettato il modulo in questo modo, permette in seguito a un collaboratore del gruppo di lavoro di recuperare questo modulo allo stato in cui si trovava nel momento in cui gli veniva attribuita questa etichetta, anche se nel frattempo il lavoro è andato avanti. L'esempio seguente si riferisce all'utente semproni che si fa una copia locale del modulo esercizi/c/ nella propria directory personale, allo stato in cui si trovavano i file nel momento dell'attribuzione dell'etichetta c-1.

semproni:~$ cvs checkout -r c-1 esercizi/c

Il comando cvs rtag è simile, ma si può riferire solo a dei moduli interi. La stessa etichettatura mostrata sopra avrebbe potuto essere realizzata nel modo seguente:

tizio:~$ cvs rtag c-1 esercizi/c/

cvs rtag: Tagging esercizi/c

172.3   Riferimenti

Appunti di informatica libera 2003.01.01 --- Copyright © 2000-2003 Daniele Giacomini -- daniele @ swlibero.org

Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome cvs_introduzione.html

[successivo] [precedente] [inizio] [fine] [indice generale] [violazione GPL] [translators] [docinfo] [indice analitico]