Un paio di giorni fa ho finalmente deciso di buttare a mare un vecchio repository svn per abbracciare git anche nell’ultimo progetto dove non lo utilizzavo, ecco quindi un sintetico tutorial su come trasformare un repository svn in repository git. Da parte mia ho seguito il tutorial di Atlassian, che però è abbastanza lungo e non tutti i passi erano necessari al mio scopo: trasformare un repository svn in repository git, una volta e per sempre, abbandonando poi il vecchio repository ma mantenendo tutto lo storico e gli utenti del vecchio repository.
Lo strumento
Di modi per fare questa trasformazione ce ne saranno parecchi, io ho usato il svn-migration-scripts.jar messo a disposizione da Atlassian, un classico eseguibile Java.
Scaricatelo e mettetelo nella home o dove preferite, ma tenente presente che i comandi seguenti sono stati scritti avendo il jar nella home dell’utente.
La preparazione
Detto che una migrazione andrebbe fatta in un momento idoneo possibilmente durante il quale il repository origine rimarrà inalterato, che dovrebbe essere eseguita da chi di dovere, e che se si vuole velocizzare le operazioni bisognerebbe lavorare sulla stessa macchina del repository svn o quantomeno nella stessa lan, ipotizziamo che sia tutto a posto e iniziamo.
Per prima cosa bisogna verificare le precondizioni, ovvero accertarsi che sul sistema ci sia tutto il necessario per eseguire la conversione.
Eseguendo il jar con il parametro “verify” viene controllato il sistema con stampa a video delle eventuali mancanze.
java -jar ~/svn-migration-scripts.jar verify
Se state eseguendo la migrazione su un Mac bisogna prima creare e montare un disco case-sensitive, sul quale sarà creato il nuovo repository:
java -jar ~/svn-migration-scripts.jar create-disk-image 5 GitMigration
L’esecuzione di questo comando crea un disco chiamato “GitMigration”
Mapping degli utenti
Nel vecchio repository i commit erano associati a utenti identificati da un nome, ma su git gli utenti sono identificati da nome e email. Andiamo quindi a creare – dentro il disco virtuale creato al passo precedente – un file authors.txt
contenente il mapping tra vecchi e nuovi utenti.
cd GitMigration
java -jar ~/svn-migration-scripts.jar authors svn://repository_url/repository_name > authors.txt
Questo crea un file di mapping contente sulla sinistra i nomi degli utenti presenti sul vecchio sistema, e sulla destra i nomi e le email da usare sul nuovo sistema. Naturalmente quelli di destinazione sono solo ipotesi, e infatti le email sono di pura invenzione (le email sono tutte nella forma “username@mycompany.com”). Andiamo quindi a sostituire le email e se vogliamo i nomi degli utenti, salviamo e passiamo al punto successivo.
Clonazione del repository
È finalmente giunto il momento della trasformazione… ma qui lo script di Atlassian ci abbandona e il git inizia a farla da padrone.
Se il repository svn di partenza ha una struttura standard, con un “trunk” contenente il codice del ramo principale, una cartella “tags” contenente tutti i tags e così via possiamo lanciare il comando seguente, con parametro “stdlayout”.
git svn clone --stdlayout --authors-file=authors.txt svn://repository_url/repository_name new_repository_name
Se al contrario abbiamo una struttura non così standard possiamo andare a specificare dove devono essere letti i dati relativi a trunk, branches e tags. Nel mio caso il trunk non era presente perché i sorgenti del ramo principale erano semplicemente in una cartella nella root del repository, quindi non ho potuto usare il parametro “–stdlayout” e ho dovuto specificare le destinazioni delle varie cartelle.
git svn clone --trunk=/folderName --branches=/branches --tags=/tags --authors-file=authors.txt svn://repository_url/repository_name new_repository_name
La trasformazione generalmente richiede alcuni minuti, pochi se avete solo qualche centinaio di commit e siete in lan (o meglio ancora sulla stessa macchina del repository), molti di più se state lavorando con un repository enorme che risiede dall’altra parte del mondo.
Al termine dell’esecuzione nel disco virtuale “GitMigration” comparirà il neonato repository git, ovvero una cartella contenente i sorgenti e tutti i dati necessari a git (la cartella nascosta .git).
Pulizia del repository git
Il repository git creato al passo precedente è ancora “collegato” a svn, infatti l’origin punta al vecchio repository e tutto è “costruito” in modo da poter continuare a centralizzare i commit sul vecchio repository.
Se il nostro obiettivo è quello di tagliare i ponti con il passato, abbandonare svn e creare un nuovo origin git, quello che dobbiamo fare ora è lanciare lo script necessario per trasformare branches e tags nel classico formato git.
java -Dfile.encoding=utf-8 -jar ~/svn-migration-scripts.jar clean-git --force
Creazione di un nuovo origin
La trasformazione è ormai compiuta e non ha più senso mantenere nel nuovo repository un riferimento al vecchio repository svn, conviene quindi eliminare l’origin e crearne uno nuovo.
Andiamo quindi a creare sul server più adatto a mantenere una copia dei nostri sorgenti un repository git.
Spostiamoci sul server, creiamo una cartella repository_name.git
, settiamone i permessi/gruppi/proprietario, e inizializziamo il repository con il comando git init --bare repository_name.git
.
A questo punto non resta altro da fare che modificare l’origin del repository git sostituendo l’url del vecchio repository svn con quello del repository remoto appena creato (utilizzando il protocollo che riteniamo più adatto, nel mio caso l’ssh), eseguire il primo push e il gioco è fatto.
Come server dei sorgenti nessuno ci vieta di utilizzare servizi web come BitBucket o GitHub, ma se il cloud vi fa paura un server linux in locale va benissimo, anche perché essendo git un sistema decentralizzato e distribuito eventuali problemi al server non sarebbero la fine del mondo.
Se al termine qualcosa non vi torna (ad esempio non riuscite a togliere il vecchio origin come è successo a me) un nuovo clone
del repository remoto non guasta, anche per verificare che sul server sia tutto a posto.
Conclusioni
Nessuno ci obbliga a sostituire il sistema che usiamo per fare il versioning dei nostri progetti, ma se inizierete a usare git vedrete che il gioco vale la candela e presto o tardi ne sentirete la mancanza quando dovrete tornare all’svn o peggio a sistemi ancora più vecchi. Si può decidere di trasformare il repository in git continuando a mantenere svn sul server, ma secondo me se si decide di cambiare conviene farlo in modo netto, e con i semplici passi che ho elencato la transizione dovrebbe essere veloce e indolore.