Appunti su Windows.
Il controllo revisioni

Cos'è il controllo delle revisioni

Supponete di essere dei programmatori e di stare sviluppando un software per conto vostro. Un vantaggio che vorreste avere è quello di poter ritornare a un precedente stato del vostro codice. Ovviamente una soluzione potrebbe essere quella di fare periodicamente delle copie di backup del progetto rinominandole con dei numeri di versione. Questo modo porta chiaramente a uno spreco di spazio e a una gestione non semplice delle revisioni, cioè delle modifiche che avete fatto a un file.

Immaginate ora di non essere gli unici sviluppatori di un software. In questo caso si aggiunge la forte complicazione di come gestire le revisioni fatte dagli altri. È proprio per rispondere a questa esigenza che nacquero negli anni '70 del 1900 i primi software per il controllo revisione.

Il modello lock-modify-unlock

Come è normale aspettarsi, la maniera più semplice per gestire un gruppo di utenti che lavora su un progetto comune, è quello di usare un server centrale con uno spazio condiviso su cui si trova il codice sorgente (repositorio centrale - central repository) e avere un sistema di blocco dei file. In pratica lo sviluppatore che decide di effettuare una modifica su di un file, lo deve prima prendere in consegna in maniera esclusiva, cioè deve bloccare (lock) l'accesso in scrittura a tutti gli altri, successivamente può quindi modificarlo (modify) e infine lo sblocca in modo che la nuova versione del file sia a disposizione di tutti, anche per eventuali altre modifiche. Da qui il nome lock-modify-unlock.

Un sistema basato sul lock-modify-unlock necessita per sua natura di un repository centrale da cui tutti devono attingere. Questo sistema fu adottato nei primi software per il controllo revisione. Tra questi SCCS e RCS. La gestione del repositorio può essere fatta sia dai soli client (pericoloso) o più comunemente da un software apposito che gira sul server e che si fa carico di tutte le richieste dei client.

Il modello copy-modify-merge

Il modello lock-modify-unlock portava inevitabilmente a delle situazioni in cui uno sviluppatore si dimenticava di togliere un lock a un file oppure uno sviluppatore che manteneva questo lock troppo a lungo.

Nacque così negli anni '80, l'idea di permettere a più utenti di modificare lo stesso file simultaneamente e di gestire poi in maniera semiautomatica l'inclusione delle modifiche nel repositorio centrale (merge). Nacque così il software CVS che sta per Concurrent Versions System. Rimaneva comunque la possibilità di effettuare il lock. Anche in questo caso l'approccio normale era quello di avere un software che girava sul server per smistare tutte le richieste dei client CVS.

Le revisioni "atomiche"

Un altro problema era che le modifiche dei file venivano viste in maniera indipendente e non come un corpus unico consistente. Per esempio immaginate di voler inserire un nuovo menù in una applicazione: dovete modificare sia il file che descrive l'interfaccia grafica, sia uno o più file che descrivono le azioni connesse a quel menù. Oppure immaginate di voler rendere compatibile il vostro software con un altro, dovrete magari modificare decine di file. Queste modifiche a diversi file erano viste come indipendenti e annullabili singolarmente. Ovviamente una maniera intelligente è invece quella di raggrupparle sotto un'unica grande modifica che in gergo viene detta atomica, cioè indivisibile, nel senso che dividerla in revisioni minori non ha senso.

Per ovviare a questi problemi nel 2000 nacque SVN, che sta per Subversion, molto simile a CVS come impostazione ma con tutta una serie di migliorie tra cui la gestione delle revisioni atomiche. SVN è uno dei software per il controllo revisione più diffusi al mondo. Si propone di essere il successore di CVS (e c'è riuscito). Anche in SVN c'è la possibilità di continuare a usare il lock dei file. SVN normalmente viene distribuito in due versioni: server e client. C'è però anche la possibilità di far funzionare SVN senza un server. In questo modo i client si possano interfacciarsi direttamente con il repositorio, senza la mediazione del server. Questo modo però è fortemente sconsigliato per ovvi motivi.

Purtroppo non sempre si ha la possibilità di installare il server SVN su qualsiasi macchina. Basti pensare a una azienda che vi dà uno spazio FTP e basta. Come fare? A questo proposito sono nati dei programmi più semplici che demandano tutto il lavoro al client che si connette allo spazio FTP e tramite un sistema di file gestisce il lock e quant'altro. Tra questi il più famoso è FtpVC.

I repository distribuiti

Negli anni '90 si cominciarono a intravedere anche i primi software per il controllo revisione basati su un modello distribuito. Non esiste più un repositorio centrale. Ognuno ha sulla propria macchina il suo repositorio e il suo storico. La sincronizzazione con gli altri utenti è volontaria e non obbligatoria.

Si può ancora usare un "repository centrale", che però non sarà nient'altro che un repositorio di un utente fittizio che raccoglie sempre tutte le modifiche ma che non ne effettua mai nessuna. Oppure si può anche scegliere che il "repository centrale" sia il repositorio gestito dal leader del gruppo. Come si può notare il fatto che ci sia un repositorio centrale è perché gli sviluppatori decidono che quello sia un repositorio centrale.

Questa gestione delle cose non permette ovviamente l'applicazione di un modello lock-modify-unlock perché non esiste un repositorio privilegiato.

Quale scegliere?

Come si dice sempre in queste occasioni, non esiste lo strumento perfetto: dovete scegliere quello più adatto alle vostre esigenze.

Supponiamo che lavoriate in un piccolo gruppo e su un progetto che ha pochi file. Un modo per applicare il modello lock-modify-unlock è quello di mettere il progetto su uno spazio condiviso (un NAS, una condivisione di rete, ecc...) e poi fare il lock rinominando il file che si vuole modificare, per esempio aggiungendo in fondo al nome del file, il nome dell'utente che lo sta modificando. Una volta finita la modifica, il file verrà rimesso al suo posto sul server e il vecchio file rinominato verrà eliminato. Questo metodo manuale dei poveri ovviamente non garantisce alcuna sicurezza e soprattutto non permette un controllo delle revisioni. Necessita di frequenti backup. È buono però per un gruppo che modifica dei file binari, come un gruppo di ricercatori che lavora su dei file di analisi dati binari (per esempio prodotti da Origin).

Se il vostro progetto contiene molti file binari, per esempio una documentazione tecnica composta da molti file Word, è obbligatorio usare un sistema basato sul modello lock-modify-unlock. Infatti se due persone modificano contemporaneamente un file Word, o in generale un file binario, è impossibile poi fare il merge delle modifiche! In questo caso è consigliabile un software come SVN che permette il lock ma che ha anche la possibilità delle modifiche simultanee per quei file su cui ha senso usare questo metodo di lavoro. Un programma commerciale simile e molto famoso è Perforce.

Se si ha a disposizione solo un server FTP su cui si vuole mettere il repositorio centrale, si può usare: FtpVC (Molto buono. Dopo 30 giorni scade il periodi di prova. Dopodiché o lo si compra oppure tutte le funzionalità (a parte la semplice lettura di file) vengono disabilitate diventando quindi inutile. A pagamento); FTPVCS (progetto morto nel 2005. Nessuna documentazione ma il software è molto buono); FtpVcs (piuttosto buono).

Se invece il vostro progetto contiene principalmente file di testo, come appunto un progetto di sviluppo di software, avete la libertà di scegliere sia un sistema centralizzato (SVN) sia un sistema distribuito. Negli ultimi anni ci si sta spostando sempre più verso sistemi di controllo revisione distribuiti. Tra i software più famosi Mercurial, Git, Bazaar.

Alcuni software di controllo revisione centralizzati basati su un server FTP

FTPVCS

Purtroppo questo software nonostante sia l'unico nel genere ad essere open-source è stato abbandonato nel 2005. Lo tratterò comunque perché ancora funzionante.

La prima volta che il programma partirà vi chiederà alcune informazioni per identificarvi. Specificate solo nome e cognome (Francesco Biccari) e la vostra email (francesco.biccari@altervista.org). Le altre opzioni le potrete modificare anche in seguito.

Le impostazioni vengono salvate in:

[HOME]\Documenti\FTPVCS\Temp\

mentre nella directory

[HOME]\Documenti\FTPVCS\Output\

verranno salvati, ognuno in una propria cartella, i progetti a cui vi connettete di volta in volta.

Ora si aprirà il programma vero e proprio. Cliccate su connect... Cominceremo a connetterci a una cartella ftp. New... Scegliete un nome qualsiasi per la connessione (di solito progetto@utente, test@francesco), mettete l'indirizzo del server FTP e la password (da notare che l'amministratore del server può darvi sia delle credenziali private, cioè una per ogni utente oppure un username e una password uguali per tutto il gruppo che lavora su quel progetto). Mettete Passive Mode (se avete problemi toglietelo. È più sicuro ma necessita che l'amministratore del server FTP abbia configurato tutto correttamente). E infine togliete la slash nella remote directory (BUG).

Date OK e vi verrà chiesto se creare dei file utili a ftpvcs sulla directory remota nel caso questi non siano già presenti. In poche parole se sono già presenti significa che voi siete solo un utente come altri, se invece non ci sono FTPVCS vi considera amministratori e vi chiede se volete voi creare un progetto. Rispondete yes. Ora usate un nome per il progetto, ovviamente inventatelo nel caso il progetto lo stiate facendo voi oppure se vi state solo connettendo a un progetto già esistente allora usate ovviamente il nome del progetto o almeno un nome sensato (Test).

Sconnettetevi dal progetto appena creato e riconnettetevi (BUG), così verrà creata la cartella locale del progetto.

[HOME]\Documenti\FTPVCS\Output\Test\

Ci fermiano un attimo per ribadire un concetto importante: la struttura delle directory usata da FTPVCS. La directory remota (opzionale) è la directory radice del progetto che si trova sul server FTP. Ovviamente se ne può specificare una per ogni progetto ("connessione"). La directory locale è invece una sola e dentro di essa viene creata una cartella per ogni progetto, con il nome, ovviamente del progetto. Un esempio:

% progetto pippo sul server FTP
ftp://serveraddress/pippo_project/

% ed ecco dove verranno messi localmente i file del progetto pippo
[HOME]\Documenti\FTPVCS\Output\pippo\

Ora siete pronti per lavorare. Se il progetto è nuovo non ci sarà alcun file presente sul server. Vediamo come si aggiungono i file. Andate nella directory locale di lavoro e create un file qualsiasi, per esempio pippo.txt. (notate la presenza della cartella _ftpvcs).

Per mettere sul server il vostro nuovo file, aggiornate FTPVCS, comparirà il file pippo.txt. Tasto destro -> Lock, Tasto destro -> Put, mettete un commento se volete altrimenti cliccate Cancel. Ora il file verrà uploadato sul server. Se avete anche finito di lavorare su quel file fate Tasto Destro -> Unlock. Ora anche gli altri potranno prendere quel file e modificarlo.

Purtroppo la stessa operazione non può essere fatta per le directory intere. Se create una directory localmente e ci mettete dei file dentro, questa non comparirà quando aggiornate FTPVCS. Dovrete creare una cartella con lo stesso identico nome da dentro FTPVCS. Solo allora potrete uploadere al solito modo (anche facendo una selezione multipla) i file nuovi.

Supponiamo ora che dei file siano già presenti nella directory remota del progetto, perché messi da voi o da altri. Supponiamo che vogliate lavorare su uno o più di questi file e non vogliate che gli altri possano modificarli. Bene. Selezionate i file di vostro interesse, cliccate su Lock, e poi su Edit (oppure su Get e poi li editate aprendoli nella cartella locale). Dopo che avrete finito con il modificare i file salvateli e chiudete il programma usato. Ora aggiornate FTPVCS e vedrete che i file modificati riporteranno l'attributo Modified. Se siete contenti delle modifiche fate Put e poi Unlock. Altrimenti solo Unlock.

Se fate doppio click su un file nella finestra di FTPVCS è come se faceste Get.

Purtroppo i file locali, quando non sono lockati da voi, risultano editabili! I programmi di questo tipo invece dovrebbero metterli in sola lettura (FtpVC e FtpVcs lo fanno). (BUG)

Sebbene sia molto spartano e abbia un po' di problemi questo software ha il grosso vantaggio di riprodurre sul server una struttura dei dati molto semplice. Questo permette di avere la cartella remota sostanzialmente uguale a quella locale in modo che in un futuro, anche se FTPVCS non sarà più utilizzabile, i dati siano accessibile semplicemente, come in una semplice cartella. Tutto il resto, cioè le vecchie versioni ecc... sono contenute nella cartella del server _ftpvcs.

Per togliere manualmente il lock a un file...

FtpVcs

Questo software è più moderno e tutt'ora manutenuto. Purtroppo per scaricarlo bisogna chiedere una username e password agli autori che oltretutto ancora non hanno deciso con che licensa rilasciarlo. Senza contare poi che la documentazione e il sito web sono in tedesco!

Se si crea un nuovo progetto, creare un nuovo progetto... Credenziali per il server. Amministratore del progetto (solo per la gestione utenti). Utenti. Poi utente locale. nuovo repository server (username e password del server) gestione utenti. Chi crea il repository è colui che scegli tutto. Chi è l'amministratore e chi sono i singoli utenti. Tutti gli utenti avranno verosimilmente la stessa username e password per il server. Avranno poi una username e password per connettersi al server FtpVcs che in realtà poi non esiste. Sono solo file scritti sull'FTP che FtpVcs rispetta. Quindi scegliere una user e password per l'amministratore del repository. Questo utente non può fare operazioni sui file ma solo sulla gestione utenti. Dovete creare un profilo anche per lui. Poi aggiungere quanti utenti si vogliono. Poi alla fine ci si connette al server ma prima bisogna dire quale è la directory locale che fa da "mirror" al repository FTP e soprattutto che utente siete. Ovviamente dovrete scegliere una user tra quelli che avete aggiunto prima nella lista. Mi raccomando non l'admin. Quello non si può connettere! Serve solo per la gestione del repository!

Se ci si connette ad un progetto già esistente, connettersi e basta.

L'aggiornamento della schermata è automatico e non manuale! Non c'è bisogno di prendere in checkout un file nuovo per aggiungerlo in remoto! I file non lockati vengono messi automaticamente in sola lettura! Sfortunatamente nel caso in cui dobbiate leggere i file sul server senza usare FtpVcs ci sono dei problemi, infatti i file non sono come voi li vedete ma vengono distribuiti in molte cartelle e rinominati con dei numeri.

Software moderni per il controllo revisione

SVN

Funzionamento server-less di SVN. È sufficiente scaricare un client, per esempio TortoiseSVN. Date il seguente comando nella condivisione Windows dove volete creare il progetto (oppure tasto destro -> Crea repository).

svnadmin create \\PC-REPO\public\progetto

Ora la cartella condivisa "progetto" che verrà creata dal precedente comando sarà il repositorio.

Supponiamo che voi siete l'utente1 che vuole cominciare a lavorare. Prima di tutto dovete copiare il repositorio in locale (checkout), creando la vostra working copy. Mettetevi in una cartella dove volete che venga creata la cartella che racchiude la working copy del progetto, dopodiché

svn checkout file://PC-REPO/public/progetto

Oppure tasto destro -> checkout...

Attenzione che su internet la gestione dei repository serverless è molto poco trattata. Oltretutto si trovano vecchie convenzioni in cui i segni di slash andavano "escaped", quindi si possono trovare comandi di questo tipo svn checkout file://PC-REPO/public/progetto con ben 5 slash!!! Tutto questo ora non è più necessario, anzi vi da errore.

Ora dimenticatevi del repositorio e aprite la vostra working copy. Create un nuovo file nella maniera classica (per esempio tasto destro -> Nuovo -> documento di testo). Ora per iniziare a considerare il nuovo file dovete fare tasto destro -> TortoiseSVN -> Add... o sulla cartella oppure sul singolo file.

Questo non significa che il nuovo file si trova già sul repositorio! Per inviare le vostre modifiche al repositorio dovete fare un "commit". Non pensate però di avere sul repositorio una copia uguale a quella che vedete nella vostra working copy! Sul repositorio i file sono immagazzinati come differenze tra le versioni. Non vedrete mai il file pippo.txt come lo vedete nella vostra working copy!

Se però avete messo il vostro repository su una directory condivisa è perché, oltre alla semplicità, volete anche rendere disponibile a chiunque una copia dell'ultima revisione del progetto, tramite accesso alla condivisione Windows. Per fare questo dovete usare il comando snv export.

svn export directory target
svn export URL target

La prima riga si usa quando volete esportare una working copy, la seconda se volete esportare direttamente un repositorio. Al posto di directory e target metterete i percorsi del vostro filesystem. Al posto di URL dovete mettere non un semplice percorso ma un URL completo, che può essere remoto (http://..., svn://..., ecc...) oppure locale (file://...).

Ecco una sintetica guida a SVN lato client.

Ecco un'altra ottima guida per SVN, stavolta molto più approfondita.

Quando si comincia a lavorare conviene fare sempre un svn update in modo da prendere le nuove modifiche fatte dagli altri nel frattempo.

Se si vuole importare un progetto locale, sul repositorio bisogna usare il comando svn import.

Mercurial

L'installazione di Mercurial è banale.

Aggiungere la PATH in Windows. Creare nella propria home sia su Win che Lin, il file Mercurial.ini.

[ui]
editor = "C:\Program Files\Notepad++\notepad++.exe" -multiInst -nosession
username = Francesco Biccari <.....@........>

Senza quelle due opzioni che ho dato a Notepad++, il commit restituirà sempre l'errore "abort: empty commit message".

Come funziona... ancora non l'ho ben capito

Comandi utili:
hg init [project]
hg add [file]
hg commit [file] [-m MESSAGE]
hg status
hg diff
hg cp ORIGIN DESTINATION
hg mv ORIGINAL TARGET
hg rm FILE
hg addremove --similarity 100
hg log
hg update [#]
hg identify -n
hg update [NAME]
hg merge
hg resolve
hg clone
hg incoming
hg pull
hg push
hg rollback
hg help [COMANDO]

Supponiamo di avere un NAS con condivisioni CIFS oppure un semplice PC con condivisioni CIFS. Creiamo una cartella e dentro di questa diamo il comando hg init. Così creiamo il progetto. Come si fa a creare un progetto sul server quando già una parte del progetto sta su un pc locale?

Gli utenti poi devono fare un clone del progetto con hg clone.

Poi fanno tutte le modifiche del caso e alla fine fanno un hg push.