Git, Mercurial e Bazaar a confronto
Ho discusso in un precedente blog i limiti di CVS e Subversion. In particolare ho evidenziato come i branch risultano difficili con CVS/SNV e di conseguenza poco utilizzati dai programmatori, anche se il loro utilizzo porterebbe diversi vantaggi.
La soluzione a questi problemi è arrivata negli ultimi anni da tre strumenti - Git, Mercurial e Bazaar - che si pongono come obiettivo non solo di semplificare il branching ma di dare una nuova prospettiva all’intero concetto di versionamento.
Distributed Version Control System (DVCS)
I tre strumenti che vado ad analizzare appartengono alla categoria dei sistemi di versionamento distribuiti. Invece di avere un repository centralizzato e tanti check-out locali (uno per ogni sviluppatore) come avveniva tradizionalmente, i DVCS propongono di dare ad ogni sviluppatore un repository locale su cui lavorare e di sincronizzare ogni tanto i vari repository.
I repository locali sono tutti alla pari cioè, con un’eccezione per Bazaar, non esiste un repository principale e tanti repository secondari. Certo si può eleggere un repository come quello di riferimento: per esempio si può dire che il repository su cui lavora il capo-progetto è quello principale. Ma questa è sono una scelta organizzativa degli sviluppatori, non uno schema imposto dagli strumenti. Quindi di base tutti i repository sono alla pari.
Ogni repository locale è completamente funzionante. Se ho un repository sul mio hard disk posso fare un check-out di qualunque revisione, apportare modifiche, committarle e perfino avere branch diversi. Tutto questo avviene in isolamento, senza che il mio lavoro influisca su quello degli altri sviluppatori o viceversa senza che io veda quello che fanno gli altri. Posso anche staccarmi dalla rete e rimanere isolato indefinitamente.
Quando però si vuole condividere e sincronizzare il lavoro fatto localmente da diversi sviluppatori la possibilità c’è. Tramite operazioni di ‘pull’ e di ‘push’ è possibile importare o esportare modifiche tra repository diversi. Si tratta comunque di sincronizzazioni fra due repository alla volta, non di pubblicazione verso tutti i repository.
Dove nascono i DVCS?
I tre DVCS in oggetto hanno tutti come punto di inizio la cosiddetta “controversia su BitKeeper”. BitKeeper è lo strumento di versionamento distribuito commerciale che Linus Torvalds e gli sviluppatori del kernel di Linux utilizzavano fino a tre anni per gestire il loro codice. Tre anni fa, per varie ragioni fra cui un possibile tentativo di reverse-engineering del prodotto, BitKeeper ha ritirato la licenza che dava gratuitamente a Linux in quanto progetto open. Questa, insieme alla cronica assenza di buoni strumenti di versionamento open-source, è la ragione per cui è iniziato lo sviluppo dei vari Git, Mercurial e Bazaar.
Perché usare un DVCS?
La prima risposta potrebbe essere: abbiamo parlato di Linux e di progetti open-source mantenuti dalla community; se la community è distribuita (in senso geografico) allora anche gli strumenti di versionamento devono essere distribuiti.
Giusto? Solo in parte. A ben guardare anche CVS e SVN permettono di lavorare in modo distribuito, anche se con il vincolo del repository centralizzato. In realtà ci sono due motivi più profondi.
Il primo motivo è che distribuendo ad ogni sviluppatore un repository è come se ogni sviluppatore lavorasse su un branch dedicato. Abbiamo già detto che lo sviluppatore può lavorare localmente in isolamento: in un certo senso questo è esattamente lo stesso effetto che si ottiene lavorando su un branch in un approccio tradizionale alla CVS/SVN. Inoltre quando lo sviluppatore effettua un push/pull fra repository effettua un’operazione simile al merge fra branch. In conclusione, i DVCS favoriscono e rendono facile lavorare su più branch - una cosa positiva.
Il secondo motivo è il miglior controllo e coordinamento degli sviluppatori. All’apparenza i DVCS e l’idea dei repository ‘alla pari’ sembrano portare ad una perdita di controllo sullo sviluppo. In realtà non è così. Infatti, il coordinatore di un progetto può decidere di fare ‘pull’ cioè di sincronizzare il proprio repository solo con un numero ristretto di persone fidate. A loro volta queste persone hanno un altro gruppo, più ampio, di persone fidate. Ne risulta uno schema molto strutturato basato sulla fiducia e sulla divisione delle responsabilità. Per confronto in CVS/SVN, l’unico controllo è quello su chi può o non può fare commit sul repository centrale: chi può fare commit deve essere molto fidato e ha i benefici del versionamento; chi non può fare commit non ha invece nessun beneficio dal versionamento e praticamente è escluso dallo sviluppo.
Fare il grande salto
State lavorando su un progetto importante per un grande cliente. Proponete alla squadra: “Ok ragazzi. Buttiamo via CVS e usiamo questo nuovo bellissimo DVCS: è scritto in Python, permette di tenere tanti repository dove si vuole, hanno cominciato a scriverlo tre anni fa e la versione 1.0 è uscita qualche settimana fa”. Ci sarà un’alzata di sopracciglia collettiva.
Digerire la filosofia dei DVCS non è facile. E’ una cosa psicologica: funzionano bene ma si sente la mancanza di un repository centrale.
Quello che posso consigliare è di provare questi tool cercando, all’inizio, di riprodurre lo schema di collaborazione tradizionale. Basta mettere un repository ‘ufficiale’ su un file system condiviso e lasciare che gli sviluppatori creino i loro repository locali e si sincronizzino solo con il repository centrale.
Con la pratica apprezzerete i vantaggi. Un consiglio? Createvi un repository sul portatile e andate a lavorare da un cliente per una settimana. Potrete fare commit e avere i vantaggi del versionamento anche senza mai accedere al repository centrale in ufficio.
Tante semplificazioni
I problemi di merge multipli evidenziati nel precedente blog scompaiono. Tutti i DVCS tracciano in modo completo le dipendenze fra revisioni, incluso i merge. Ne risulta un minor numero di conflitti.
I DVCS mantengono l’intero repository in una sola directory (chiamata .git .hg o .bzr a seconda dello strumento). Addio alle directory CVS e .svn sparse per l’intero albero.
I DVCS permettono di creare il repository con un semplice comando ‘init’ eseguito nella directory principale del progetto. Addio ai menosissimi import+checkout di CVS/SVN.
Git
Git è una collezione di script shell e di programmi in C scritta originariamente da Linus Torvalds. Fra gli utilizzatori, Linux e Ruby on Rails. Lo strumento utilizza un’interfaccia a linea di comando ma è anche incluso un front-end grafico (gitk) per visualizzare il grafo delle revisioni.
Fra i principi di design hanno grande rilevanza le prestazioni anche in caso di repository grandi. Lo strumento è ricco di funzionalità, anche di nicchia. Questo si riflette sull’alto numero di comandi e parametri che danno un’impressione frammentata dell’insieme. E’ l’unico strumento che prevede comandi espliciti per la manutenzione del repository (una specie di garbage collection).
Come IDE Java, Git è supportato da Eclipse e IntelliJ IDEA.
Mercurial
Mercurial è scritto in Python con alcune parti in C. Fra gli utilizzatori ci sono i progetti NetBeans, OpenJDK, OpenSolaris e Mozilla.
L’interfaccia è tramite comandi shell. I comandi sono pochi, intuitivi e con parametri semplici. Sembra a volte che Mercurial sia stato progettato a partire dai comandi utenti: tutto è intuitivo e mi sono trovato già a indovinare con successo la sintassi dei comandi senza consultare il manuale.
Questa semplicità non va a scapito della funzionalità, che è completa per le operazioni fondamentali.
Un potenziale limite dello strumento è il fatto che non versiona le directory vuote.
Mercurial è supportato da Eclipse, NetBeans (integrato in 6.1) e IntelliJ IDEA.
Bazaar
Bazaar è scritto in Python e ha come principale produttore e sponsor Canonical, l’azienda dietro a Ubuntu Linux, oltre ad altri progetti open.
La principale differenza è che supporta vari modelli di collaborazione (detti workflow) fra cui centralizzato e decentralizzato, con o senza un gatekeeper con ruolo privilegiato.
Anche qui l’interfaccia è tramite comandi shell. I comandi sono facili ma non facilissimi soprattutto se si usano le funzionalità più avanzate.
Stando al sito, Bazaar ha anche dalla sua un solido testing automatizzato, che però non ho verificato direttamente.
Bazaar è supportato da Eclipse e IntelliJ IDEA.
Il confronto
Sarò breve. E’ difficile trasmettere in poche parole ore e ore di esperimenti fatti sui vari tool. Comunque credo che il mio giudizio possa aiutarvi se guardate questi tool per la prima volta.
Innanzitutto le differenze fra i tre tool (e differenze ci sono) sono più imputabili a diversi livelli di maturità che a impostazioni di design diversi. Cioè secondo me fra qualche anno, quando si saranno stabilizzati, saranno praticamente identici.
Per esempio in fatto di prestazioni o documentazione gli strumenti stanno giocando a rincorrersi. Ogni mese, con l’uscita di nuove release, la situazione cambia.
Comunque… se oggi dovessi buttare un tool giù dalla torre sarebbe indubbiamente git. Troppi comandi, troppi parametri, troppa terminologia. Faccio un esempio. Se voglio tornare ad una revisione passata lo posso fare ma la copia che ottengo sarà di tipo “detached”, cioè sarà un caso particolare che va gestito in modo particolare. Ma serve? A mio parere no e infatti gli altri due tool riescono a gestire questa situazione come un caso normale senza introdurre nuova terminologia o sintassi particolari.
Fra Mercurial e Bazaar la scelta è più difficile. Mercurial ha un ‘appeal’ immediato dovuta ai comandi eccezionalmente intuitivi. Ma Bazaar ha delle feature in più, prima fra tutte la possibilità di scegliere fra workflow di collaborazione diversi.
Inoltre c’è la questione delle directory vuote, che in Mercurial non sono gestite: questo sembra un piccolo difetto di design che sta cominciando a dare più grattacapi del previsto (c’è per esempio un bug aperto riguardante il caso in cui lo stesso nome è utizzato in un branch per un file e in un altro branch per una directory).
Per riassumere, Mercurial è più usabile mentre Bazaar ha più feature e un più solido design.
Per i miei progetti alla fine ho scelto Mercurial e il motivo è dovuto al più vasto supporto sulle IDE Java. In questo momento in particolare non posso rinunciare a NetBeans, e Bazaar su NetBeans non è supportato.
Il supporto da parte delle IDE è però destinato a migliorare nel futuro ed è possibile che io passi a IntelliJ IDEA, che supporta già Bazaar. Allora rivaluterò la mia scelta e forse… forse… passerò a Bazaar.


Aprile 23rd, 2008 11:07
Per l’uso con Visual Studio 2005 e 2008 ci sono supporti du qualche tipo? Questi strumenti funzionano anche per windows o girano solamente sotto Linux? Grazie.
Aprile 23rd, 2008 12:57
Mercurial e Bazaar girano anche su Windows. Git funziona ma tramite CygWin.