Guida al CVS di Gentoo Linux

Contenuti:

1.Introduzione

Struttura del documento 

Questa guida è divisa in due parti, la prima mostra come usare il CVS per i non sviluppatori, per esempio insegna come scaricare i sorgenti dal CVS e tenerli aggiornati. La seconda parte vi spiega come fare uso del CVS da sviluppatore, mostrandovi come modificare, aggiungere e rimuovere files dal CVS e svolgere altri incarichi di manutenzione. Se non avete mai preso in mano nulla sui CVS, è raccomandato iniziare dalla prima sezione e procedere poi alla seconda; se avete un'esperienza basilare, potrete trovare tutto ciò che vi serve nella seconda sezione, ma potrebbe esservi utile un ripasso della prima parte.

Cos'è il CVS e come funziona? 

Il CVS è un sistema client/server che permette agli sviluppatori di raccogliere i propri progetti in un archivio centrale chiamato repository (letteralmente magazzino, si è prediletto il termine inglese per il suo frequente utilizzo NdT). Usando il client CVS, gli sviluppatori possono applicare cambiamenti al repository. Il repository tiene traccia di ogni cambiamento effettuato su ogni singolo file, creando un archivio completo dell'evoluzione dello sviluppo del programma. Gli sviluppatori possono richiedere vecchie versioni di un particolare file sorgente, vedere i logs dei cambiamenti e svolgere altri utili compiti quando richiesto.

Il ruolo del CVS 

Molti progetti opensource possiedono un proprio server CVS, usato dagli sviluppatori come archivio centrale di tutto il lavoro. Gli sviluppatori spesso migliorano i sorgenti quotidianamente e di solito i programmatori sono sparsi in giro per il mondo, così il CVS fornisce il meccanismo necessario per unire i loro progetti in un archivio centralizzato. Il CVS costituisce il "collante" che permette a questi sviluppatori di variare il codice sorgente senza pestarsi i piedi, senza perdere dati importanti ed impedendo disguidi su aggiornamenti importanti da parte di altri.

CVS -- gli ultimi sorgenti degli sviluppatori 

Quando gli sviluppatori saranno pronti, essi scaricheranno parte del loro lavoro dal CVS, lo comprimeranno sotto forma di un file .tar.gz e lo rilasceranno come una nuova versione ufficiale del programma. Comunque, l'ultima versione ufficiale spesso non è abbastanza aggiornata per una varietà di possibili motivi. Nella prima sezione di questa guida, vi mostrerò come utilizzare il CVS a questo scopo -- scaricare l'ultima versione dei sorgenti ad uso personale.

Installare CVS 

Per installare cvs, digitate emerge cvs:

Esempio 1: Installare CVS

# emerge cvs

CVSROOT 

Prima di iniziare, ci sono alcune nozioni basilari sul CVS che dovreste sapere. La prima è che per connettersi ad un repository, prima di tutto dovrete conoscere un percorso chiamato "CVSROOT". Esso è una stringa, come un indirizzo internet, che dice al comando cvs dove si trova il repository e come connettersi ad esso. Giusto per rendere il tutto più interessante, CVS ha un certo numero di formati per il CVSROOT, che dipendono dal fatto che il repository sia locale o remoto e dal metodo utilizzato per connettersi ad esso. Ecco alcuni esempi di CVSROOTs, seguiti da spiegazioni.

Un CVSROOT locale 

Esempio 2

CVSROOT=/var/cvsroot

Ecco un esempio di CVSROOT locale, userete un percorso come questo per connettersi ad un repository presente sul vostro computer in /var/cvsroot o ad un repository montato via NFS in /var/cvsroot.

Un CVS di un server remoto con password 

Esempio 3

CVSROOT=:pserver:cvs@foo.bar.com:/var/cvsroot

Ecco un esempio di CVSROOT per un repository remoto che esiste sul dominio foo.bar.com e si trova nella directory /var/cvsroot su quella macchina. La stringa ":pserver:" dice al client di connettersi a questo server usando il protocollo CVS password, presente nel CVS. Di solito, i repository pubblici usano questo protocollo per permettere accesso anonimo agli utenti.

Un CVSROOT remoto che fa uso di rsh/ssh 

Esempio 4

CVSROOT=drobbins@foo.bar.com:/data/cvs

Ecco un esempio di CVSROOT che sfrutta i protocolli RSH o SSH; in questo esempio, il server CVS tenterà di accedere al repository su foo.bar.com usando l'account drobbins. Se la variabile CVS_RSH è settata a "ssh", allora il nostro client cvs tenterà di utilizzare ssh per connettersi, altrimenti sarà utilizzato rsh. Il metodo d'accesso ssh è apprezzato da quelli che si preoccupano della sicurezza, comunque nè il sistema RSH nè quello SSH permettono il login anonimo. Per utilizzarli dovrete avere un account su foo.bar.com.

Altri due concetti... 

Oltre al CVSROOT, dovrete conoscere anche il nome del modulo (insieme di sorgenti) cui vorrete accedere, così come la password per il login anonimo su un server che fa uso del protocollo CVS password. Contrariamente a quanto avviene per un ftp anonimo, non c'è un formato "standard" per la password del CVS, così dovrete farvela dare da chi mantiene il sito web o dagli stessi sviluppatori. Una volta avute tutte queste informazioni sarete pronti per cominciare.

Interagire col CVS, parte 1 

Ottenere i sorgenti è un processo diviso in due fasi. Prima di tutto, accediamo al server password, quindi scarichiamo i sorgenti con il comando checkout. Ecco un esempio di un set di comandi utilizzati per controllare gli ultimi sorgenti di Samba, un famoso progetto di integrazione UNIX/Windows.

Esempio 5

# export CVSROOT=:pserver:cvs@pserver.samba.org:/cvsroot

Il primo comando assegna un valore alla variabile CVSROOT, se non settate questa variabile i prossimi due comandi richiederanno anche un -d:pserver:cvs@pserver.samba.org:/cvsroot a seguito del comando cvs. Esportare questa variabile ci risparmia un po' di battitura.

Interagire con CVS, parte 2 

Ecco i comandi necessari per scaricare una copia degli attuali sorgenti degli sviluppatori. Probabilmente vorrete passare al prossimo paragrafo per leggere la spiegazione di questi comandi e poi tornare qui:

Esempio 6

# cvs login
(Accesso a cvs@pserver.samba.org)
CVS password: (inserire la password)

# cvs -z5 co samba
U samba/COPYING
U samba/Manifest
U samba/README
U samba/Read-Manifest-Now
U samba/Roadmap
U samba/WHATSNEW.txt
(questa è solo una parte dell'output completo)

Interagire col CVS -- spiegazione 

Il primo comando ci connette al pserver ed il secondo dice al nostro client CVS di controllare il modulo samba utilizzando una compressione gzip di livello 5 per velocizzare il trasferimento. Per ogni nuovo file creato localmente, il cvs scrive a schermo "U [percorso]" ad indicare che quello specifico file è stato aggiornato sul disco.

Controllo completo 

Una volta che il controllo è stato completato, noterete una directory "samba" nel percorso dove stavate lavorando che conterrà gli ultimi sorgenti. Noterete anche che tutte le directory hanno una sottocartella "CVS" all'interno -- CVS raccoglie informazioni sull'account in queste directories e possono tranquillamente venire ignorate. D'ora in avanti, non dobbiamo preoccuparci di aver settato la variabile CVSROOT nè abbiamo bisogno bisogno di specificarla nella riga di comando, perchè ora è contenuta dentro tutte quelle directories "CVS". Ricordate -- avrete bisogno della variabile CVSROOT solo per l'iniziale accesso e per il controllo.

Aggiornare i sorgenti 

Beh, ci siamo -- nuovi sorgenti! Adesso che avete i sorgenti, potete andare avanti compilandoli ed installandoli, studiandoli o facendovi quello che volete.

Ogni tanto vorrete mettere in pari la vostra directory dei sorgenti con la versione corrente del CVS. Per farlo, non avete bisogno di accedere di nuovo al pserver; anche le vostre informazioni per il login sono contenute all'interno delle cartelle "CVS". Prima di tutto, entrate nella directory principale (in questo caso "samba") e scrivete:

Esempio 7

# cvs update -dP

Un'occhiata all'aggiornamento del cvs, parte 1 

Se ci sono nuovi files, cvs stamperà a schermo una linea "U [percorso]" per ognuno di essi man mano che li aggiorna. Inoltre, se avete compilato i sorgenti, probabilmente troverete un sacco di linee "? [percorso]"; questi sono files che il cvs non individua come provenienti dal repository remoto.

Un'occhiata all'aggiornamento del cvs, parte 2 

Osservate inoltre le due opzioni passate alla linea di comando per l'aggiornamento del cvs, "-d" dice di creare le nuove directories che possono essere state aggiunte al repository (ciò di norma non viene fatto) e "-P" dice al cvs di rimuovere tutte le cartelle vuote dalla copia scaricata. "-P" è una buona idea, perchè il cvs ha la tendenza di generare col tempo un sacco di directories vuote (una volta usate, ora non più).

Quando dovete semplicemente scaricare gli ultimi sorgenti, questo è tutto quel che dovete conoscere. Ora vediamo come interagire col CVS da sviluppatore.

2.CVS per sviluppatori

Modificare files 

Come sviluppatori, avrete bisogno di modificare i files sul CVS, per fare ciò fate semplicemente i cambiamenti appropriati alla vostra copia in locale del repository. I cambiamenti che fate ai sorgenti non sono applicati al repository remoto finchè non dite al cvs di farlo. Quando avete verificato che tutte le modifiche funzionano correttamente e siete pronti per applicarle, seguite questo procedimento diviso in due passi. Prima di tutto, aggiornate i sorgenti scrivendo il seguente comando nella cartella principale:

Esempio 8

# cvs update -dP

Il CVS unisce i cambiamenti degli altri ai nostri 

Come abbiam visto prima, l'aggiornamento del cvs metterà in pari i vostri sorgenti con la versione contenuta nel repository -- ma cosa accade ai cambiamenti fatti? Non preoccupatevi, essi non sono scartati. Se un altro sviluppatore applica modifiche ad un file che non avete toccato, i vostri files locali verranno aggiornati per essere in pari con la versione nel repository.

E se avete modificato le linee 1-10 di un file locale ed un altro sviluppatore ha cancellato le linee 40-50, ne ha aggiunte 12 alla fine, modificato le linee 30-40 e quindi applicato i cambiamenti al repository prima di voi, cvs intelligentemente applicherà queste modifiche nella vostra copia in locale facendo in modo che i cambiamenti fatti da voi non siano persi. Questo permette a due o più sviluppatori di lavorare su parti differenti dello stesso file allo stesso momento.

La combinazione non è perfetta 

Comunque, se due o più sviluppatori hanno applicato cambiamenti alla stessa regione dello stesso file, le cose diventano un pochino più complicate. Se ciò accade, allora cvs vi dirà che c'è stato un conflitto. Il lavoro non sarà perso, ma sarà richiesto un intervento manuale, perchè ora cvs richiede un input su come combinare i cambiamenti contrastanti.

L'invio dei cambiamenti 

Vedremo esattamente come i conflitti possano essere risolti rapidamente, ma per ora mettiamo caso che non vi siano problemi dopo che avete scritto "cvs update -dP" -- di solito non ce ne sono. Senza conflitti, i vostri sorgenti locali sono aggiornati e siete pronti ad inviare i vostri cambiamenti al repository scrivendo il seguente comando nella directory principale:

Esempio 9

# cvs commit

Cosa succede inviando i cambiamenti 

"cvs commit" non applica soltanto cambiamenti al repository. Prima di farlo effettivamente, cvs aprirà il vostro editor di testo preferito così che possiate scrivere una breve descrizione delle modifiche. Una volta che avrete inserito i vostri commenti, salvate il file ed uscite, i cambiamenti ed i commenti saranno applicati al repository remoto e saranno disponibili per gli altri sviluppatori.

Vedere i logs 

E' davvero facile vedere tutto l'archivio dei cambiamenti di un certo file, corredato dei commenti che gli sviluppatori (voi compresi) avete scritto. Per vedere queste informazioni, scrivete:

Esempio 10

# cvs log myfile.c

Il comando "cvs log" è ricorsivo, così se volete vedere le informazioni per un'intera directory, semplicemente entrateci e scrivete:

Esempio 11

# cvs log | less

Opzioni per l'invio 

Potrete volere utilizzare un altro editor piuttosto che quello che il cvs apre di norma quando scrivete "cvs commit". In questo caso, semplicemente settate la variabile EDITOR al nome dell'editor che volete utilizzare. Mettere un opzione come questa nel vostro ~/.bashrc potrebbe essere una buona idea:

Esempio 12

export EDITOR=jpico

In alternativa, potete specificare un messaggio di log come opzione nella linea di comando, così che cvs non abbia bisogno di caricare l'editor:

Esempio 13

# cvs commit -m 'Ho sistemato dei piccoli errori in portage.py'

Il file .cvsrc 

Prima di studiare altri comandi di cvs, raccomando di preparare un file ~/.cvsrc. Creandolo, potrete dire al cvs di utilizzare le opzioni preferite di norma da voi, così non avrete bisogno di ricordarvi di scriverle ogni volta. Questo è un utile esempio (raccomandato) di .cvsrc:

Esempio 14

cvs -q  
diff -u -b -B
checkout -P
update -d -P

Il file .cvsrc, continua 

Oltre a definire utili opzioni per alcuni comandi cvs, la prima linea di .cvsrc attiva la modalità silenziosa per il cvs, che ha il beneficio principale di rendere l'output degli aggiornamenti del cvs più conciso e leggibile. Inoltre, dopo che avrete sistemato questo .cvsrc nel percorso appropriato, potrete scrivere cvs update invece di cvs update -dP.

Aggiungere un file al repository 

E' davvero facile aggiungere un file sorgente al CVS. Dapprima, create il file con il vostro editor di testo preferito, quindi scrivete:

Esempio 15

# cvs add myfile.c
cvs server: use 'cvs commit' to add this file permanently

Questo dice al cvs di aggiungere questo file al repository la prossima volta che farete un cvs commit. Fino ad allora, gli altri sviluppatori non potranno vederlo.

Aggiungere una directory al repository 

Aggiungere una directory al CVS è abbastanza simile ad aggiungere un file:

Esempio 16

# mkdir foo
# cvs add foo
La directory /var/cvsroot/mycode/foo è stata aggiunta al repository.  

Diversamente da quando aggiungete un file, quando aggiungete una directory essa appare immediatamente nel repository e non è necessario un cvs commit. Una volta che avrete aggiunto una directory locale al cvs, noterete che una cartella "CVS" è stata creata all'interno di essa come contenitore per le informazioni sull'accesso cvs. Così potete facilmente dire se una certa directory è stata aggiunta al cvs guardando nella cartella "CVS".

Note per le aggiunte al cvs 

Oh, potevate indovinarlo, prima di aggiungere un file o una directory al repository, dovete assicurarvi che la directory principale sia già stata aggiunta al CVS, altrimenti riceverete un errore come questo:

Esempio 17

# cvs add myfile.c
cvs add: cannot open CVS/Entries for reading: No such file or directory
cvs [add aborted]: no repository  

Prendere familiarità con "cvs update", parte 1 

Prima di vedere come risolvere i conflitti, facciamo pratica con l'output del comando "cvs update". Se avete creato un file ~/.cvsrc che contiene una linea "cvs -q", noterete che l'output del comando è molto più facile da leggere. "cvs update" vi informa di cosa fa e ve lo mostra scrivendo un singolo carattere, uno spazio ed il nome di un file, come nell'esempio:

Esempio 18

# cvs update -dP
? distfiles
? packages
? profiles 

Prendere familiarità con "cvs update", parte 2 

"cvs update" usa il carattere "?" per dire che non sa nulla di quel file che trova nella copia locale del repository. Esso non è ufficialmente parte del repository. Ecco una lista di tutti gli altri caratteri informativi di cui fa uso CVS:

Esempio 19

U [path]

Usato quando un nuovo file è creato nel repository locale o un file non toccato da voi è stato aggiornato.

Esempio 20

A [path]

Questo file è in lista per essere aggiunto e verrà ufficialmente messo nel repository quando si eseguirà un cvs commit.

Prendere familiarità con "cvs update", parte 3 

Esempio 21

R [path]

Similmente ad una "A", una "R" vi fa sapere che il file è in lista per essere rimosso dal repository al prossimo cvs commit.

Esempio 22

M [path]

Significa che questo file è stato modificato da voi; inoltre è possibile che nuovi cambiamenti dal repository siano stati combinati con successo nel file.

Esempio 23

C [path]

Il carattere "C" indica che questo file è in conflitto e richiede una sistemazione manuale prima di poter eseguire "cvs commit".

Introduzione alla risoluzione dei conflitti 

Ora vediamo come risolvere un conflitto. Sono molto coinvolto nel progetto Gentoo Linux ed abbiamo il nostro server cvs su cvs.gentoo.org. Noi sviluppatori spendiamo la maggior parte del nostro tempo a lavorare sui sorgenti del modulo "gentoo-x86". All'interno di esso, abbiamo un file chiamato "Changelog" che ospita (avete indovinato!) una descrizione dei cambiamenti maggiori apportati ai files nel repository.

Un esempio di conflitto 

Poichè questo file è modificato quasi ogni volta che uno sviluppatore applica un importante cambiamento al cvs, è una sorgente primaria di conflitti -- eccone un esempio. Ammettiamo che io abbia aggiunto queste righe all'inizio del Changelog:

Esempio 24

data 25 Feb 2001
 
La mia aggiunta

Comunque, diciamo che prima che io possa inviare queste 3 righe, un altro sviluppatore aggiunga quanto segue in cima al Changelog ed invii i cambiamenti:

Esempio 25

data 25 Feb 2001
 
L'aggiunta di un altro sviluppatore

Continuazione sull'esempio di conflitto 

Ora, quando eseguo cvs update -dP (come dovreste fare prima di ogni invio), il cvs non è capace di combinare questi cambiamenti nella mia copia locale del Changelog, perchè abbiamo entrambi aggiunto linee alla stessa parte del file -- come può il cvs sapere che versione usare? Così ricevo quest'errore:

Esempio 26

RCS file: /var/cvsroot/gentoo-x86/ChangeLog,v
retrieving revision 1.362
retrieving revision 1.363
Merging differences between 1.362 and 1.363 into ChangeLog
rcsmerge: warning: conflicts during merge
cvs server: conflicts found in ChangeLog
C ChangeLog

Risoluzione dei conflitti, parte 1 

Argh -- un conflitto! Fortunatamente, correggerlo è semplice. Se apro il mio editor di testo favorito, noto queste linee in cima al Changelog:

Esempio 27

<<<<<<< ChangeLog
data 25 Feb 2001
 
La mia aggiunta
 
=======
data 25 Feb 2001
 
L'aggiunta di un altro sviluppatore
 
>>>>>>> 1.363

Risoluzione dei conflitti, parte 2 

Anzichè prediligere una versione, il cvs le ha aggiunte entrambe al file Changelog e le ha circondate con speciali separatori per far notare chiaramente il conflitto. Ora dipende da me sostituire questa sezione con il resto che dovrebbe apparire nel ChangeLog; in questo caso, la sostituzione non è nessuna della due versioni, ma una combinazione di entrambe:

Esempio 28

data 25 Feb 2001

La mia aggiunta

L'aggiunta di un altro sviluppatore

Ora che ho sostituito la sezione del file in conflitto in modo appropriato e rimosso i delimitatori, posso inviare i miei cambiamenti al cvs senza problemi.

Trucchetti per la risoluzione dei conflitti 

Quando dovete modificare un file a causa di conflitti, assicuratevi di controllarli tutto per individuare tutti i problemi; se vi siete dimenticati di correggere un conflitto, il cvs non vi permettere di inviare finchè non sarà risolto! E' anche ovviamente molto importante rimuovere gli speciali limitatori che il cvs ha aggiunto al file. Un altro suggerimento -- se fate un errore mentre sistemate il conflitto e poi ("D'oh!") per sbaglio salvate le modifiche, potete trovare una copia del vecchio file in ".#nomefile.versione".

Rimuovere un file 

Ora è il momento di imparare l'ultima nozione sul CVS -- rimuovere dei files dal repository. E' un processo suddiviso in due fasi: dapprima, cancellate il file dalla vostra copia locale dei sorgenti e quindi utilizzare il comando cvs remove:

Esempio 29

# rm myoldfile.c
# cvs remove myoldfile.c

Rimuovere un file, continuazione 

Il file sarà quindi messo in elenco per la rimozione la prossima volta che eseguite un invio. Una volta fatto ciò, il file sarà ufficialmente cancellato dalla versione corrente del repository. Comunque, il cvs non eliminerà questo file e terrà un archivio completo dei suoi contenuti e delle sue modifiche, se in casi vi servisse ancora in futuro. Questo è solo uno dei tanti modi con cui il cvs protegge il vostro prezioso codice sorgente.

cvs remove è ricorsivo, ciò vuol dire che potete cancellare un gruppo di files e poi lanciare il comando senza argomenti dalla directory principale. Fare ciò metterà tutti i files cancellati in lista per essere rimossi al prossimo invio.

Rimuovere una directory 

Se volete rimuovere un'intera directory, vi raccomando il seguente procedimento. Dapprima, cancellate fisicamente tutti i files al suo interno ed eseguite "cvs remove":

Esempio 30

# rm *.c
# cvs remove

Rimuovere una directory, continuazione 

Quindi inviate i cambiamenti:

Esempio 31

# cvs commit

Ecco il trucco, fate quanto segue per cancellare la directory:

Esempio 32

# cd ..
# cvs remove mydir
# rm -rf mydir

Notate che rimuovere una directory non richiede un "cvs commit" -- le cartelle sono aggiunte e rimosse dal repository in tempo reale.

Fine! 

La vostra introduzione al CVS è completa -- spero che questo tutorial vi sia stato utile. Sul CVS c'è molto più di quanto io abbia potuto coprire in questa guida introduttiva, ma per fortuna ci sono un po' di ottimi siti che potete consultare per aumentare la vostra conoscenza:

Su questo documento 

La versione originale di questo articolo è stata pubblicata per la prima volta su IBM developerWorks, ed è di proprietà di Westtech Information Services. Questo documento è una versione aggiornata dell'articolo originale, e contiene vari miglioramenti fatti dal team di documentazione Gentoo Linux.



Ultimo aggiorn.:
2005-05-23
Daniel Robbins
Autore

Xavier Neys
Redazione

Stefano Calzavara
Traduzione

Stefano Lucidi
Revisione della traduzione

Sommario:  Questa guida introduce i lettori al CVS, il Concurrent Versions System, usato dagli sviluppatori di tutto il mondo per produrre programmi in modo flessibile ed in collaborazione con altri. Realizzata per utenti alle prime armi, questa guida darà rapidamente sia agli utenti che ad i nuovi sviluppatori una rapida infarinatura. Sia che vogliate fare uso del CVS per provare gli ultimi sorgenti di un certo programma, sia che vogliate iniziare ad usare il CVS per sviluppare, questo documento fa al caso vostro.
- 2002 Gentoo.it - Domande, commenti e/o correzioni? Email gentoo-dev@gentoo.it.