[an error occurred while processing this directive]
diff logo Informatica e sistemi alternativi
su questo sito sul Web
    Home   Chi siamo    Contattaci    Scrivi per diff    Proponi un argomento 27/02/17
    Cos'è diff    Come accedere    F.A.Q.    Promuovi    Dicono di diff    Amici di diff    
AmigaOS
Linux
FreeBSD
BeOS
OpenSource
Java
Database
Informatica
Hardware
E-Commerce
Narrativa

Introduzione al CVS
di Ferruccio Zamuner

CVS è un acronimo di Concurrent Version System, ovvero è un sistema di gestione di versioni concorrente.
La domanda che sorge spontanea è: che cosa è un sistema di gestione di versioni?.
Per rendere più comprensibile il concetto vediamo una situazione comune non solo nell'ambito della programmazione: ho redatto un'offerta, il mio socio dopo averla letta mi chiede di modificarla, operazione che eseguo. Quando l'offerta viene data al commerciale questi si accorge che non sono state contemplate tutte le voci richieste dal cliente e quindi richiede una ulteriore modifica, prima di presentarla al cliente per la trattativa.

  • Se memorizzo ogni versione dell'offerta con lo stesso file, non ho nessun modo di riprendere un'edizione precedente, nè ho modo di tracciare il lavoro svolto per ad esempio giustificare il tempo impiegato.
  • Se cambio a ciascuna versione il nome del file, dopo 10 revisioni avrò 10 documenti e non sempre mi sarà possibile essere certo di trovare l'ultima versione, la quarta o la penultima. Inoltre lo spazio occupato sarà 10 volte maggiore del caso precedente.

Utilizzando un sistema di tipo CVS o RCS (Revision Control System) posso gestire tutte le versioni che desidero dello stesso documento ed estrarne la versione ennesima in qualsiasi momento.

Il fatto che sia "concorrente" significa che quella stessa offerta può essere modificata direttamente dal socio, dal commerciale e da tutti quelli che abilito senza dover intervenire in prima persona, e non solo, ciascuno può apportare le modifiche che desidera anche simultaneamente agli altri.

Il problema per la reale applicazione di questo strumento in un ambiente d'ufficio è la cattiva abitudine di gestire i documenti in formati diversi dal semplice testo (anche quando non necessario), formato in cui i sistemi di gestione di versioni operano.

Certo che se però il documento in questione è un file in linguaggio sorgente (C, Perl, HTML, Java, etc.) questi utilissimi strumenti funzionano a meraviglia: non solo mi permette di tener traccia delle versioni, consentendomi di inserire dei commenti per ricodarmi le modifiche apportate ogni volta, ma memorizza il documento iniziale e per ciascuna versione solo le differenze dalla precedente, risparmiando molto spazio disco. Inoltre l'ambiente di lavoro risulta sensibilmente più ordinato.

Altro dettaglio non trascurabile è che posso gestire delle collezioni di file sorgente raggruppati in directory assegnando al tempo x una specifica versione per lo stato di ciascuno di essi.
In questo modo potrei memorizzare ad esempio lo stato di un sito che sto pubblicando per un cliente, senza dover perdere il lavoro già eseguito ogni volta che apporto delle modifiche.

Il fatto che CVS sia concorrente mi consente di avere diverso personale che opera sullo stesso sito senza per questo trovarmi in uno stato inconsistente.

A cosa serve il CVS?

CVS traccia la storia di un albero di sorgenti, nell'ambito di una serie di modifiche. Per ciascuna modifica aggiunge ai file editati alcuni dati utili come la data e l'ora della modifica, il nome della persona che ha modificato il file.
Di solito chi ha apportato le modifiche fornisce un breve commento che, memorizzato nel giornale delle modifiche del file (log), descrive cosa ha modificato e perchè. Con queste informazioni, CVS può aiutare gli sviluppatori a rispondere a domande del tipo:

  • Chi ha apportato questa modifica?
  • Quando è stata fatta?
  • Perché è stato modificato?
  • Quali altri cambiamenti sono stati inseriti allo stesso tempo?

Come si usa CVS

Prima di discutere di alcuni termini e concetti per ora troppo vaghi, andiamo a vedere i comandi principali del CVS.

Configurazione del repository

CVS registra le modifiche di tutti per un progetto specifico in una directory chiamata repository (in italiano ripostiglio). Prima che tu possa usare CVS, devi inizializzare la variabile d'ambiente CVSROOT con il percorso del repository.
Di solito è un compito del manager della configurazione del progetto inizializzare tale variabile, è comunque importante che tu lo sappia, probabilmente troverai già la definizione globale pronta per CVSROOT da qualche parte.

In ogni caso, sul nostro sistema, il repository CVS è `/usr/src/master'. In questo caso, dovrai inserire i seguenti comandi

setenv CVSROOT /usr/src/master

se la tua shell è csh o derivata da essa,

CVSROOT=/usr/src/master
export CVSROOT

se la tua shell è Bash o qualche altra variante della Bourn shell.

Se ti dimentichi di questi comandi, CVS si lagnerà quando proverai ad usarlo:

$ cvs checkout httpc
cvs checkout: No CVSROOT specified!  Please use the `-d' option
cvs [checkout aborted]: or set the CVSROOT environment variable.
$

Estrazione di una directory di lavoro

CVS non funziona in una directory qualsiasi, devi lavorare in una directory che sia stata creata per te da CVS.
Proprio come quando prendi un libro dalla biblioteca e prima di portarlo a casa per leggerlo devi registrarne il prestito, allo stesso modo qui devi eseguire il comando cvs checkout prima di lavorarci sopra.
Per esempio, immaginiamo che stai lavorando su un progetto chiamato httpc, un semplice client HTTP:

$ cd
$ cvs checkout httpc
cvs checkout: Updating httpc
U httpc/.cvsignore
U httpc/Makefile
U httpc/httpc.c
U httpc/poll-server
$

Il comando cvs checkout httpc significa, "Estrai l'albero di sorgenti chiamato httpc dal ripostiglio specificato nella variabile CVSROOT."

CVS mette l'albero relativo in una sotto-directory che si chiamerà `httpc':

$ cd httpc
$ ls -l
total 8
drwxr-xr-x  2 mario         512 Oct 31 11:04 CVS
-rw-r--r--  1 mario          89 Oct 31 10:42 Makefile
-rw-r--r--  1 mario        4432 Oct 31 10:45 httpc.c
-rwxr-xr-x  1 mario         460 Oct 30 10:21 poll-server

Molti di questi files sono la tua copia di lavoro dei sorgenti httpc. Comunque, la sotto directory chiamata `CVS' (la prima) è qualcosa di diverso.
CVS conterrà informazioni aggiuntive circa ciascun file nella directory, per aiutare ad individuare quali modifiche avrai fatto fino al momento del reinserimento nel ripostiglio.

La modifica dei file

Una volta creata una directory di lavoro, puoi editare, compilare e testare i file che essa contiene così come sei solito fare -- essi sono solo file.

Per esempio, supponiamo che si voglia tentare la compilazione del pacchetto che abbiamo appena estratto:

$ make
gcc -g -Wall  -lnsl -lsocket  httpc.c   -o httpc
httpc.c: In function `tcp_connection':
httpc.c:48: warning: passing arg 2 of `connect' from incompatible pointer type
$

Sembra che `httpc.c' non sia ancora stato portato su questo sistema operativo. Abbiamo la necessità di inserire un "cast" in uno degli argomenti per la funzione connect. Per fissare questo problema dovremo andare alla linea 48 ed apportare la modifica appropriata:

    if (connect (sock, &name, sizeof (name)) >=3D 0)
nella seguente:

    if (connect (sock, (struct sockaddr *) &name, sizeof (name)) >=3D 0)

Ora dovrebbe compilarsi correttamente:

$ make
gcc -g -Wall  -lnsl -lsocket  httpc.c   -o httpc
$ httpc GET http://www.diff.org
... HTML text for Diff's home page follows ...
$

Unire i tuoi cambiamenti a quelli di altri sviluppatori?

Fin quando ciascun sviluppatore fa uso della propria directory di lavoro, i cambiamenti che hai fatto non sono visibili agli altri sviluppatori del tuo gruppo. CVS non pubblica le tue modifiche fin quando non sei pronto. Quando hai eseguito tutti i test sulle tue modifiche, devi inviarle al repository per renderle disponibili anche agli altri.
Andiamo a descrivere il funzionamento del comando preposto a questo fine, il cvs commit.
Ma prima pensa a cosa può succedere se un altro ha modificato il tuo stesso file, magari la stessa linea o anche un'altra. Quale cambiamento dovrebbe prevalere?
È in genere impossibile rispondere a questa domanda automaticamente; CVS certamente non è capace di giudicare da solo.

Quindi prima che tu possa inviare le tue modifiche, CVS richiede che i tuoi sorgenti siano sincronizzati con gli altri cambiamenti già inviati dagli altri membri.
Il comando cvs update si occupa di questa fase:

$ cvs update
cvs update: Updating .
U Makefile
RCS file: /u/src/master/httpc/httpc.c,v
retrieving revision 1.6
retrieving revision 1.7
Merging differences between 1.6 and 1.7 into httpc.c
M httpc.c
$

Esaminiamo linea per linea questo output:

U Makefile
Una linea della forma `U file' significa che il file è stato semplicemente aggiornato (Updated); qualcun altro ha apportato delle modifiche al file, e CVS copia le modifiche nella tua directory.
RCS file: ...
retrieving revision 1.6
retrieving revision 1.7
Merging differences between 1.6 and 1.7 into httpc.c
Questi messaggi indicano che qualcun altro ha cambiato `httpc.c'; CVS uniche le loro modifiche alle tue, e che non ha trovato conflitti testuali. I numeri `1.6' e 1.7 sono numeri di revisione, usati per identificare un specifico punto nella storia di un file. Nota che CVS unisce le tue modifiche nella sola tua directory di lavoro, il ripostiglio e le directory di lavoro degli altri sviluppatori sono lasciate immutate. È lasciato a te di controllare che la fusione delle modifiche non crei conflitti e/o problemi.
M httpc.c
Una linea nella forma `M file' significa che il file è stato modificato Modified da te, e contiene le modifiche che non sono ancora visibili agli altri sviluppatori.
Questo file deve essere ancora inviato per rendere pubblico il tuo lavoro. In questo caso, `httpc.c' ora contiene sia le tue modifiche sia quelle di un altro utente.

Da quando il CVS ha unito i tuoi sorgenti con quelli di altri, è meglio verificare che tutto funzioni correttamente:

$ make
gcc -g -Wall -Wmissing-prototypes  -lnsl -lsocket  httpc.c   -o httpc
$ httpc GET http://www.cyclic.com
... HTML text for Cyclic Software's home page follows ...
$

Sembra che funzioni ancora.

Pubblicare le tue modifiche

Ora che hai allineato i tuoi sorgenti con quelli degli altri del gruppo ed hai verificato che tutto funziona, sei pronto per pubblicare le tue modifiche nel ripostiglio per renderle visibili a tutti.
Il solo file da te modificato è `httpc.c', tuttavia per sicurezza è meglio rieseguire il comando cvs update anche per vericare che non vi siano stati altri cambiamenti nel frattempo e per ottenere dal sistema la lista completa dei file modificati:

$ cvs update
cvs update: Updating .
M httpc.c
$

Come ci aspettavamo, il solo file che CVS menziona è `httpc.c'; e ci avverte che contiene delle modifiche che non hai ancora pubblicato. E finalmente puoi eseguire il comando

$ cvs commit httpc.c

A questo punto, CVS avvierà il tuo editor preferito e ti chiederà un messaggio di log che descriva i cambiamenti da te apportati. Quando uscirai dall'editor, CVS pubblicherà le tue modifiche:

Checking in httpc.c;
/u/src/master/httpc/httpc.c,v  <--  httpc.c
new revision: 1.8; previous revision: 1.7
$

Ora che tu hai inviato le tue modifiche, anche gli altri sviluppatori possono trarne vantaggio. Quando un altro sviluppatore eseguirà il comando cvs update, CVS unirà le tue modifiche a `httpc.c' nella sua directory di lavoro.

Esaminare le modifiche

A questo punto, potresti essere curioso di sapere quali cambiamenti gli altri sviluppatori hanno fatto al file `httpc.c'. Per vederli, visualizzerai il log con il comando cvs log:

$ cvs log httpc.c

RCS file: /u/src/master/httpc/httpc.c,v
Working file: httpc.c
head: 1.8
branch:
locks: strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 8;     selected revisions: 8
description:
The one and only source file for the trivial HTTP client
----------------------------
revision 1.8
date: 1996/10/31 20:11:14;  author: mario;  state: Exp;  lines: +1 -1
(tcp_connection): Cast address structure when calling connect.
----------------------------
revision 1.7
date: 1996/10/31 19:18:45;  author: toni;  state: Exp;  lines: +6 -2
(match_header): Make this test case-insensitive.
----------------------------
revision 1.6
date: 1996/10/31 19:15:23;  author: mario;  state: Exp;  lines: +2 -6
...
$

Buona parte del testo la potrai ignorare, ma porzione da guardare attentamente è quella che segue la prima linea di trattini di meno (-). I vari log appaiono in ordine temporale inverso, sotto l'assunzione che i più recenti siano di solito i più interessanti. Ciascun contributo contiene un cambiamento del file, e può essere interpretato come segue:

`revision 1.8'
Ciascuna versione di un file ha un unico numero di revisione. Questi numeri appaiono nella forma `1.1', `1.2', `1.3.2.2' o anche `1.3.2.2.4.5'. Normalmente la revisione 1.1 è la prima revisione di un file. A ciascuna revisione successiva è dato un nuovo numero incrementando la parte più a destra di uno.
`date: 1996/10/31 20:11:14; author: mario; ...'
Questa linea ci informa sulla data del cambiamento e lo username della persona che ha pubblicato la modifica; il resto della linea è meno interessante.
`(tcp_connection): Cast ...'
Questa è chiaramente la linea descrittiva della modifica.

Il comdnao cvs log può selezionare un intervallo per data o per revisione, vai a leggere il manuale se desideri maggiori dettagli.

Se tu desiderassi vedere realmente una modifica fatta, puoi usare il comando cvs diff. Per esempio, se ti fosse necessario vedere il cambiamento apportato da Fred pubblicato con la revisione 1.7, tu potresti usare il seguente comando:

$ cvs diff -c -r 1.6 -r 1.7 httpc.c

Prima di esaminare l'output del comando, vediamo meglio che cosa gli abbiamo chiesto:

-c
Questo richiede che cvs diff usi un formato umanamente leggibile per il suo output.
-r 1.6 -r 1.7
Con questa parte si dice a CVS di mostrare i cambiamenti necessari per passare dalla versione 1.6 alla versione 1.7. Si può richiedere un intervallo più ampio, se lo desideri; per esempio -r 1.6 -r 1.8 mostrerà le ultime modiche sia di Fred che le tue. (Puoi anche chiedere le modifiche al rovescio per passare dalla versione 1.7 alla 1.6 -r 1.7 -r 1.6. Può sembrare strano, ma qualche volta è molto utile.)
httpc.c
Questo è il nome del file da ispezionare. Se nessun file è specificato, CVS produrrà un resoconto dell'intera directory relativa al progetto.

Qui c'è l'output del comando:

Index: httpc.c

RCS file: /u/src/master/httpc/httpc.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -c -r1.6 -r1.7
*** httpc.c     1996/10/31 19:15:23     1.6
--- httpc.c     1996/10/31 19:18:45     1.7
***************
*** 62,68 ****
  }


! /* Return non-zero iff HEADER is a prefix of TEXT.  HEADER should be
     null-terminated; LEN is the length of TEXT.  */
  static int
  match_header (char *header, char *text, size_t len)
--- 62,69 ----
  }


! /* Return non-zero iff HEADER is a prefix of TEXT, ignoring
!    differences in case.  HEADER should be lower-case, and
     null-terminated; LEN is the length of TEXT.  */
  static int
  match_header (char *header, char *text, size_t len)
***************
*** 76,81 ****
--- 77,84 ----
    for (i =3D 0; i < header_len; i++)
      {
        char t =3D text[i];
+       if ('A' <=3D t && t <=3D 'Z')
+         t +=3D 'a' - 'A';
        if (header[i] !=3D t)
          return 0;
      }
$

Questo output richiede un po' di sforzo per essere utilizzato, ma è estremamente significativo e merita l'impegno per capirlo.

La parte interessante inizia con le prime due linee che iniziano con *** e --- che descrivono le differenze rispettivamente tra il file più vecchio e quello aggiornato.
Il resto consiste in due pezzi (hunk), ciascuno dei quali inizia con una linea di asterischi. Qui c'è il primo pezzo:

***************
*** 62,68 ****
  }


! /* Return non-zero iff HEADER is a prefix of TEXT.  HEADER should be
     null-terminated; LEN is the length of TEXT.  */
  static int
  match_header (char *header, char *text, size_t len)
--- 62,69 ----
  }


! /* Return non-zero iff HEADER is a prefix of TEXT, ignoring
!    differences in case.  HEADER should be lower-case, and
     null-terminated; LEN is the length of TEXT.  */
  static int
  match_header (char *header, char *text, size_t len)

Il testo dalla versione più vecchia appare dopo la linea *** 62,68 ***; il testo più recente è quello che segue la linea --- 62,69 ---. La coppia di numeri di ciascuna linea indica l'intervallo di linee mostrato. CVS fornisce il contesto attorno alle modifiche, e segna le attuali linee affette dalla modifica con i caratteri `!'. Quindi si può notare che la singola linea nella metà superiore è stata rimpiazzata con le due linee visualizzate nella metà inferiore.

Qui c'è un secondo hunk:

***************
*** 76,81 ****
--- 77,84 ----
    for (i =3D 0; i < header_len; i++)
      {
        char t =3D text[i];
+       if ('A' <=3D t && t <=3D 'Z')
+         t +=3D 'a' - 'A';
        if (header[i] !=3D t)
        return 0;
      }

Questa parte descrive l'inserimento di due linee, segnate con i caratteri `+'.
CVS omette il testo vecchio in questo caso, perché sarebbe ridondante. CVS usa un formato analogo per le linee rimosse.

Come per il comando Unix diff, l'output del cvs diff è normalmente chiamato patch, perchè gli sviluppatori per tradizione usano questo comando per distribuire i bug fix o nuove piccole caratteriche. Mentre è abbastanza leggibile per noi umani, esso contiene informazioni sufficienti per un programma per applicare le modifiche che descrive al testo originale.
Infatti, il comando Unix patch esegue esattamente questa operazione, dato un patch come input.

Aggiungere e cancellare i file

CVS tratta la creazione e la cancellazione di file esattamente come le altre modifiche, registrando tali eventi nella storia dei file. Un modo per comprendere meglio è dire che CVS registra la storia delle directory allo stesso modo della storia dei file in esse contenuti.

CVS non può assumere i nuovi file automaticamente sotto il suo controllo, sarebbe errato in molti casi; è necessario richiedergli in modo esplicito di gestire un nuovo file. Per esempio non gestisce i file oggetto, gli eseguibili, il cui contenuto tra l'altro è il risultato della compilazione dei file sorgenti.
Invece, se tu crei un nuovo file, cvs update lo segnerà con un carattere `?' finchè non gli dirai cosa intedi farne.

Per aggiungere un file ad un progetto, dovresti prima creare il file, quindi usare il comando cvs add in congiunzione al comando cvs commit per aggiungere il file al repository. Per esempio ti mostriamo come aggiungere un file README per il progetto httpc:

$ ls
CVS          Makefile     httpc.c      poll-server
$ (-:emacs:-) README
... enter a description of httpc ...
$ ls
CVS          Makefile     README       httpc.c      poll-server
$ cvs update
cvs update: Updating .
? README --- CVS doesn't know about this file yet.
$ cvs add README
cvs add: scheduling file `README' for addition
cvs add: use 'cvs commit' to add this file permanently
$ cvs update --- Now what does CVS think?
cvs update: Updating .
A README --- The file is marked for addition.
$ cvs commit README
... CVS prompts you for a log entry ...
RCS file: /usr/mario/cvs-class/rep/httpc/README,v
done
Checking in README;
/usr/src/master/httpc/README,v  <--  README
initial revision: 1.1
done
$

Allo stesso modo CVS tratta la cancellazione dei file.
Se cancelli un file ed esegui cvs update, CVS non prevede che tu intendessi rimuovere tale file. Infatti fa qualcosa di benigno -- ricrea il file con l'ultimo che aveva registrato e lo segna con un carattere `U', come per gli altri aggiornati. (Questo significa anche che se desideri semplicemente annullare ogni modifica da te apportata ad un file, puoi semplicemente cancellarlo e cvs update lo ricreerà per te.)

Per rimuovere un file da un progetto, devi prima cancellare il file, quindi usare il comando cvs rm per segnalarlo come rimosso.
Quindi la prossima volta che eseguirai cvs commit sarà cancellato anche dal ripostiglio.

Pubblicare un file segnalato con cvs rm non distruggerà il file nè la sua storia. Esso semplicemente aggiungerà una nuova revisione nella quale è marcato come "non-esistente". Il ripostiglio ancora conterrà il file con le sue precedenti versioni, e non solo potrai recuperarlo se ne avessi la necessità, ma anche esaminarlo con cvs diff o cvs log.

Ci sono diverse strategie per cambiare i nomi ai file; la più semplice è dopo aver rinominato il file nella directory di lavoro eseguire prima un cvs rm del file con il vecchio nome, poi un cvs add con il nuovo nome.
Lo svantaggio di questa procedura è che si perdono le informazioni dei log del vecchio file che non migrano su quello nuovo.
Altre strategie evitato questo svantaggio ma hanno altri problemi.

Puoi aggiungere directory così come aggiungi i file.

Scrivere dei buoni commenti per i log

Se uno può usare cvs diff per recuperare il testo completo di un cambiamento, perchè ci si deve preoccupare di scrivere i commenti sul giornale di bordo dei file?
Ovviamente i commenti possono essere più sintetici ed espressivi delle semplici differenze tra le linee di sorgente che si possono ottenere in output dai programmi che già abbiamo visto.
In questo modo si evita al futuro lettore di perdersi in inutili dettagli e gli si consente di carpire il senso della modifica.

Comunque, un buon commento nel giornale di bordo descrive la ragione che ha spinto lo sviluppatore ad apportare la modifica.
Un esempio di commento mal fatto per la revisione 1.7 mostrata sopra potrebbe dire "Convertito T in minuscolo." Questo commento pur essendo accurato, è totalmente inutile; cvs diff fornirebbe la stessa informazione in modo più chiaro.
Un miglior commento potrebbe essere "Make this test case-insensitive," perché fa capire lo scopo chiaramente a tutti con delle parole più comprensibili: i client HTTP dovrebbero ignorare differenze tra maiuscole e minuscole quando analizzano gli header.

Gestione dei conflitti

Come menzionato prima, il comando cvs update fonde le modifiche apportate dagli altri sviluppatori con le tue nella tua directory di lavoro. Se tu e un altro sviluppatore avete modificato lo stesso file, CVS unisce il suo lavoro al tuo.

È importante immaginare come questo lavoro è svolto quando i cambiamenti incidono su regioni distanti di un file, ma che cosa succede se entrambi avete modificato la stessa linea? CVS chiama questo evento conflitto, e lascia a te il compito di risolverlo.

Per esempio, supponiamo che hai solo aggiunto alcuni controlli al codice di ricerca del host name. Prima che tu possa pubblicare la modifica, sincronizzi i tuoi sorgenti con quelli nel ripostiglio attraverso il comando cvs update.

$ cvs update
cvs update: Updating .
RCS file: /usr/src/master/httpc/httpc.c,v
retrieving revision 1.8
retrieving revision 1.9
Merging differences between 1.8 and 1.9 into httpc.c
rcsmerge: warning: conflicts during merge
cvs update: conflicts found in httpc.c
C httpc.c
$

In questo caso, un altro sviluppatore ha modificato la stessa regione dello stesso file che hai modificato tu, così CVS si lamenta del conflitto. Anzichè stampare `M httpc.c', come farebbe altrimenti, stampa `C httpc.c', per indicare che si è verificato un conflitto in quel file.

Per risolverlo, carica il file nel tuo editor. CVS segnala il conflitto nel seguente modo nel testo:

  /* Look up the IP address of the host.  */
  host_info =3D gethostbyname (hostname);
<<<<<<< httpc.c
  if (! host_info)
    {
      fprintf (stderr, "%s: host not found: %s\n", progname, hostname);
      exit (1);
    }

  if (! host_info)
    {
      printf ("httpc: no host");
      exit (1);
    }
>>>>>>> 1.9

  sock = socket (PF_INET, SOCK_STREAM, 0);

Il testo del tuo file di lavoro appare in cima, dopo i caratteri '<<<', seguono i caratteri `===', e sotto c'è il testo dell'altro sviluppatore dove si è verificato il conflitto con il tuo file.

Il numero di revisione `1.9 indica che il cambiamento che ha generato il conflitto è stato introdotto con la versione 1.9 del file, rendendo più facile per te controllare il commento sul giornale di bordo del file, o esaminare l'intera modifica con cvs diff.

Una volta che hai deciso come risolvere il problema, rimuovi i segnalini dal codice e lo sistemi come hai previsto. In questo caso poichè i tuoi cambiamenti erano migliori, potresti semplicemente buttare le modifiche dell'altro sviluppatore e lasciare il testo nel seguente modo:

  /* Look up the IP address of the host.  */
  host_info =3D gethostbyname (hostname);
  if (! host_info)
    {
      fprintf (stderr, "%s: host not found: %s\n", progname, hostname);
      exit (1);
    }

  sock =3D socket (PF_INET, SOCK_STREAM, 0);

Fatto questo rimane buona norma controllare che sia tutto a posto compilando ed eseguendo il programma (ed i suoi vari test) prima di procedere alla pubblicazione del sorgente.

$ make
gcc -g -Wall -Wmissing-prototypes  -lnsl -lsocket  httpc.c   -o httpc
$ httpc GET http://www.diff.org
HTTP/1.0 200 Document follows
Date: Thu, 18 Jan 2001 23:04:06 GMT
...
$ httpc GET http://www.sola.com
httpc: host not found: www.sola.com
$ cvs commit httpc.c

È importante capire che cosa CVS considera o meno un conflitto.
CVS non può comprendere la semantica del programma; semplicemente gestisce i sorgenti come un insieme di testi. Se uno sviluppatore aggiunge un argomento ad una funzione e corregge le chiamate ad essa mentre un secondo sviluppatore aggiunge una chiamata alla stessa funzione senza sapere che ora richiederà un argomento in più, questo genererà certamente dei problemi, ma CVS non segnalerà alcun conflitto.
I due sorgenti sono sicuramente incompatibili, ma CVS non può accorgersene, la sua comprensione dei conflitti è puramente testuale.

In pratica, fortunatamente, i conflitti sono rari. Solitamente, essi si verificano quando due sviluppatori affrontano lo stesso problema, o quando non c'è accordo sullo sviluppo del programma.
Assegnare i compiti intelligentemente ai vari sviluppatori è la maniera più ragionevole di ridurre simili conflitti.

Molti sistemi di controllo delle revisioni permettono allo sviluppatore di inserire dei "blocchi" (lock) sui file che andrà a modificare, per impedire ad altri di cambiarli in quel periodo, almeno fino a quando non saranno pubblicate le sue modifiche prima.

Mentre questo strataggemma può risolvere in alcuni casi il problema dei conflitti, non si rivela in assoluto più efficace del metodo usato da CVS.
Di solito i cambiamenti si possono unire senza problemi, mentre i programmatori sovente si dimenticano dei blocchi lasciati chiusi in giro. In entrami i casi l'esplicito lock di uno o più file causa inutili ritardi. Inoltre i blocchi prevengono solo i conflitti testuali, non possono far nulla contro i conflitti semantici del genere descritto prima, se i due sviluppatori hanno agito su file diversi.

LINUX
BSD
OPENSOURCE


Ferruccio Zamuner
Ha studiato Economia ed Informatica presso l'Università degli studi di Torino e Ingegneria informatica/automatica presso il Politecnico di Torino.
Dotato di forte intuito e di innata passione per la matematica e la geometria, si è buttato sulle scienze naturali e sulle strutture algebriche prima del fatale l'incontro con il calcolatore.
Da quasi 2 anni editore, opera come imprenditore dal 1995 dopo numerose esperienze sul fronte del software non allineato, in particolare del free software.
È titolare della NonSoLoSoft, ditta specializzata nella progettazione, realizzazione e promozione di siti web.
Letture preferite: racconti di fantascienza, fumetti, Harvard Business Review (in versione originale americana) e documentazione tecnica.

Puoi contattare l'autore scrivendo a:
ferz@diff.org


Articoli dello stesso autore:
La Storia dello sviluppo del PostgreSQL
I sistemi operativi alla prova dei mercati azionari
PostgreSQL e MySQL: differenze


 


[an error occurred while processing this directive]
© 1999,2000,2001,2002 NonSoLoSoft di Ferruccio Zamuner (Italia)- tutti i diritti sono riservati