Gentoo Logo

Guida al CVS di Gentoo Linux

Indice:

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 file 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 log 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:

Codice 1.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

Codice 1.2: Impostare CVSROOT

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

Codice 1.3: Impostare CVS con autenticazione

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

Codice 1.4: RSH/SSH CVSROOT

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.

Codice 1.5: Impostare CVSROOT

# 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:

Codice 1.6: Effettuare il check dei sorgenti

# 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 directory 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 directory "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:

Codice 1.7: Aggiornare i propri sorgenti

# cvs update -dP

Un'occhiata all'aggiornamento del cvs, parte 1

Se ci sono nuovi file, 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 file 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 directory 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 directory 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 file

Come sviluppatori, avrete bisogno di modificare i file 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:

Codice 2.1: Aggiornare sorgenti e directory

# cvs update -dP

Il CVS unisce i cambiamenti degli altri ai nostri

Come abbiamo 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 file 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:

Codice 2.2: Effettuare il commit dei cambiamenti

# 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 log

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:

Codice 2.3: Visualizzare le informazioni di log

# cvs log myfile.c

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

Codice 2.4: Visualizzare le informazioni di log con un paginatore

# 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:

Codice 2.5: Impostare il proprio editor

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:

Codice 2.6: Effettuare il commit dei cambiamenti con un breve informazione di log

# 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:

Codice 2.7: Impostazioni predefinite raccomandate

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:

Codice 2.8: Aggiungere un file

# 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:

Codice 2.9: Aggiungere una directory

# 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:

Codice 2.10: Aggiungere un file, ricevendo però un errore

# 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:

Codice 2.11: Aggiornare CVS

# 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:

Codice 2.12: Messaggio d'informazione: U

U [path]

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

Codice 2.13: Messaggio d'informazione: A

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

Codice 2.14: Messaggio d'informazione: R

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.

Codice 2.15: Messaggio d'informazione: M

M [path]

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

Codice 2.16: Messaggio d'informazione: C

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 file 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:

Codice 2.17: Voce nel Changelog

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:

Codice 2.18: Altra voce nel Changelog

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:

Codice 2.19: Errore in CVS

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:

Codice 2.20: Conflitto nel Changelog

<<<<<<< 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:

Codice 2.21: Voce nel Changelog

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 file 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:

Codice 2.22: Rimuovere un file

# 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 file e poi lanciare il comando senza argomenti dalla directory principale. Fare ciò metterà tutti i file 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 file al suo interno ed eseguite "cvs remove":

Codice 2.23: Rimuovere una directory

# rm *.c
# cvs remove

Rimuovere una directory, continuazione

Quindi inviate i cambiamenti:

Codice 2.24: Effettuare il commit delle modifiche

# cvs commit

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

Codice 2.25: Rimuovere una directory

# 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.

Recuperare una versione precedente

CSV non potrebbe essere considerato un buon sistema di controllo della versione se non fosse possibile richiamare versioni precedenti dal repository. È possibile recuperare file basandosi su una specifica data, e ovviamente anche su un numero di revisione. L'esempio seguente richiama la revisione 1.202 di file e sovrascrive la versione corrente di file:

Codice 2.26: Recuperare un file basandosi sul numero di revisione

$ cvs update -p -r 1.202 file > file

E' possibile richiamare file basandosi sulla data utilizzando il parametro -D: sono valide date intere (o timestamp), ma anche parametri relativi come yesterday (ieri, NdT) o last week (ultima settimana, NdT).

Fine!

L'introduzione al CVS è completa: l'autore spera che questo tutorial sia stato utile. Sul CVS c'è molto più di quanto si sia potuto coprire in questa guida introduttiva, ma per fortuna ci sono un po' di ottimi siti che è possibile consultare per aumentare le proprie conoscenze:

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.



Stampa

Aggiornato il 20 maggio 2008

La versione originale di questo documento non è più mantenuta

Oggetto: 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.

Daniel Robbins
Autore

Xavier Neys
Redazione

Stefano Calzavara
Traduzione

Stefano Lucidi
Traduzione

Andrea Venino
Traduzione

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.