Esperimenti con GIT e Subversion

Scritto il 18 ottobre 2011 da

Nelle scorse settimane ho fatto qualche esperimento con un nuovo flusso di lavoro basato su GIT e Subversion. Tutti i nostri progetti utilizzano Subversion come sistema di controllo dei sorgenti, pensiamo che in questo momento un sistema centralizzato risponda meglio alle nostre esigenze, tuttavia alcune feature di GIT potrebbero essere molto interessanti per gli sviluppatori, così ho iniziato ad investigare su come prendere il meglio dei due mondi e integrare GIT nel nostro flusso di lavoro basato su Subversion.

GIT è un sistema di controllo distribuito, questo significa che ogni sviluppatore riceve una copia completa di tutta la storia del progetto, quindi la prima cosa da fare è creare un clone del nostro progetto con GIT. Cercando con Google ho trovato che si tratta di un’operazione veramente molto semplice:

[marco@bridge git] git svn init -s <svn.repository.url>
[marco@bridge git] git svn fetch

Il primo comando crea un repository GIT locale nella directory corrente and lo collega al repository Subversion remoto. Il secondo comando clona il repository Subversion nel repository GIT locale. Potrebbe impiegare da pochi minuti a diverse ore in relazione alla dimensione del repository remoto, ma alla fine si ha una copia completa di branch e tags memorizzata nel repository GIT locale:

[marco@bridge git] git branch -a
* master
  remotes/rel_1_00
  remotes/refactorings
  remotes/tags/pre_rel_1_00
  remotes/trunk

Il branch master è quello collegato alla directory trunk remota di Subversion. Ogni commit eseguito sul branch master verrà inviato a Subversion con:

[marco@bridge git] git svn dcommit

Di tanto in tanto si dovranno ricevere gli aggiornamenti dal repository Subversion e aggiornare il repository GIT locale. Ancora una volta si tratta di un’operazione veramente molto semplice:

[marco@bridge git] git svn rebase

Assicuratevi di essere sul branch master e che non ci siano modifiche non committate, altrimenti il rebase non funzionerà. Il comando git stash diventa molto utile in questo caso, poichè permette di rimuovere temporaneamente tutte le modifiche senza creare un nuovo commit.

Lavorare sul branch master non è diverso dal lavorare direttamente con Subversion, con la differenza che si ha un passo in più da eseguire (dcommit) prima che le nostre modifiche vengano inviate al repository centrale. Questo è comunque un vantaggio poichè ci permette di rivedere i nostri commit e usare qualche trucco offerto da GIT, come il rebase interattivo e l’amending, per ripulire la storia del codice.

Il vantaggio principale di usare GIT è tuttavia poter creare branch locali, quindi ho cambiato il mio workflow in modo da creare un nuovo branch locale dal branch master ogni volta che inizio a lavorare ad una nuova feature, committare le modifiche quando necessario per tenere traccia dei progressi, testare il codice, committare gli aggiustamenti, ecc. Quando sono soddisfatto del risultato effettuo un merge verso il branch master e invio le modifiche al repository Subversion con dcommit. E’ con le operazioni di merge che GIT mostra tutta la sua utilità. Un semplice merge replica tutti i commit dal branch locale al master e di conseguenza verso Subversion, sporcando l’history remota con i commit locali, tuttavia un merge squash replica tutte le modifiche dal branch locale ma non effettua i commit, permettendoci di eseguire un controllo finale delle modifiche, correggere eventuali problemi dovuti al merge con un versione del codice più recente e committare tutto con un singolo commit. L’history remota non conterrà quindi i commit locali ma un singolo changeset con tutte le modifiche effettuate sul branch locale.

La procedura quindi è:

  1. Creare un branch locale
  2. Lavorare sul branch locale committando quando necessario
  3. Tornare al branch master, aggiornare dal repository remoto ed effettuare un merge squash dal branch locale
  4. Controllo finale del codice, commit e invio a Subversion

Fino ad ora questa procedura con GIT e Subversion ha funzionato abbastanza bene. Gli strumenti di sviluppo che supportano GIT purtroppo non supportano l’integrazione con Subversion e si è quindi costretti il più delle volte ad utilizzare la linea di comando. EGit, l’integrazione di GIT per Eclipse, è molto utile per gestire i repository GIT locali ma è ancora piuttosto immaturo e non offre tutte le opzioni disponibili dal programma a linea di comando. Speriamo che in futuro venga offerta una migliore integrazione.

Collegamenti: