Archivi tag: git

Tempo di migrazioni: trasformare un repository da svn a git

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.

Quando tutto sembra perduto: git reflog

Un paio di giorni fa ho avuto modo di usare una delle funzioni più belle di git, e siccome non tutti la conoscono credo sia il caso di celebrarla un po’ perché mi ha salvato qualche ora di lavoro.
Piccola premessa: ho iniziato a mettere le mani su un progetto mai visto prima e il log di git era abbastanza ordinato, quindi per fare la mia parte ho fatto un branch per la funzione che dovevo aggiungere e avevo intenzione di fare un merge e push sull’origin al termine della modifica. Non sono ancora un utilizzatore di git esperto, quindi a volte faccio delle cavolate…

Ipotizziamo di avere un progetto già avviato con alcuni commit (nel mio esempio uno), e di voler aggiungere una funzionalità. Come consigliato dal galateo facciamo un nuovo branch, ci spostiamo su di esso, facciamo dei commit (possibilmente autoconsistenti e che non rompano niente) e concludiamo la modifica.
Git reflog - Preparazione

Arriva il momento di fare il merge. Ipotizziamo di aver sbagliato qualcosa, magari perché stiamo usando un tool grafico poco chiaro, e ci ritroviamo con un po’ di leggerezza a cancellare il branch con un bel "git branch -D nomebranch".
Apparentemente tutto il nostro lavoro è andato perduto e lo scoramento ci assale mentre dalla nostra bocca esce un fiume di bestemmie e parole sconce.
Git reflog - Cancellazione branch

Quando tutto sembra perduto ci ricordiamo di aver letto che con git non si perde mai niente, perché all’occorrenza esiste anche un log parallelo al principale a cui poter attingere nei momenti di difficoltà: il reflog.
Digitiamo "git reflog" e vediamo con nostro grande sollievo che i nostri commit fatti sul branch andato perso sono ancora tutti lì in memoria, e volendo possiamo recuperarli.
Un "git reset --hard HEAD@{index}" e come per magia ritroviamo nel nostro log principale tutti i commit che erano presenti nel branch tagliato per errore.
Git reflog - Ripristino commit

Siccome siamo precisi a questo punto non possiamo non domandarci “Ma i commit non li avevo fatti un un branch secondario? Come mai me li ritrovo sul master?”.
Infatti il reset hard fatto poc’anzi salva i commit ma li mette nel master perché non sono collegati ad alcun ramo, volendo si può far eseguire il ripristino su un ramo secondario, magari chiamandolo con il nome di quello tagliato erroneamente: "git branch nomeramo HEAD@{index}"
Git reflog - Ripristino ramo

La storia è importante e non va mai dimenticata. Git lo sa, e con il reflog ci fornisce uno strumento salvifico da utilizzare nei momenti più difficili.

Titanium Studio e GIT, integrato (a volte) è meglio

Sviluppatori: ognuno con le sue convinzioni e il suo credo

Gli sviluppatori mobile con Titanium si dividono in due scuole di pensiero: chi utilizza Titanium Studio e chi preferisce usare un ide meno pompato e la console. Io appartengo ancora alla prima categoria, principalmente perché mi districo male tra molte finestre e preferisco avere sempre tutto sotto controllo mentre lavoro. L’idea di passare a Sublime o Atom in combinazione eventuale con strumenti esterni mi ha tentato, ma ancora non ho raccolto gli stimoli sufficienti.

Il problema è che Titanium non è il solo strumento che contribuisca a dividerci in caste, perché anche GIT non scherza. I puristi conoscono tutti i comandi con relativi parametri a memoria e utilizzano soltanto la console, i pigri/smemorati come me si affidano a strumenti un po’ più “smart” e ricorrono alla console solo in casi di emergenza o come esercizio di memoria. Personalmente io uso alternativamente la console, il plugin integrato nell’ide e SourceTree, un gestore di repository GIT veramente ben fatto.

SourceTree, e GIT non sarà più così ostico

SourceTree, e GIT non sarà più così ostico

La I di IDE sta per “Integrated”…

Fatte queste distinzioni è ora di arrivare al dunque: perché questo articolo? Il punto è che non sarebbe male utilizzare nel proprio ambiente di sviluppo un plugin che ci aiuti ad avere sempre sotto controllo tutte le modifiche fatte ai nostri sorgenti. Eclipse ha degli showview integrati (History e Synchronize) con cui poter vedere lo storico e lo stato attuale delle modifiche, ma in Titanium questi non funzionano con GIT. Infatti l’ide Titanium Studio ha un suo plugin per GIT (com.aptana.git), che però si integra malissimo con Eclipse e secondo me è praticamente inutile.

Come guardare il dettaglio dei plugin installati

Come guardare il dettaglio dei plugin installati

Aptana Git, per la serie: meglio soli che mal accompagnati

Aptana Git, per la serie: meglio soli che mal accompagnati


L’amato/odiato Eclipse ha un suo plugin per gestire decentemente il repository GIT (EGit), ma non viene fornito con Titanium Studio e fa a cazzotti con quello installato di default.
Il mio consiglio è quindi quello di disabilitare il plugin di Aptana e utilizzare EGit, e ora vi mostro come fare.

Installazione e utilizzo di EGit su Titanium Studio

Punto 1: Per prima cosa conviene dire a Eclipse di non utilizzare più il plugin di Aptana per gestire i nuovi progetti GIT aggiunti nel workspace. Questa cosa la si fa dalla pagina delle preferenze di Eclipse.

Disabilitazione di Aptana Git per i nuovi progetti

Disabilitazione di Aptana Git per i nuovi progetti

Punto 2: Se volete usare su Eclipse un plugin non fornito di default (in questo caso EGit) bisogna installarcelo. La procedura è sempre la stessa e ne avevo parlato in modo un po’ più dettagliato su un precedente articolo (a proposito di SVN su Eclipse).

Installazione di EGit

Installazione di EGit

Punto 3: Nel caso abbiate già dei progetti che utilizzano GIT come VCS all’interno del vostro workspace questi continueranno a usare il vecchio plugin. Scollegateli da esso e fate in modo che usino il nuovo plugin.

Disconnessione di progetti esistenti da Aptana Git

Disconnessione di progetti esistenti da Aptana Git

Connessione di EGit ai progetti git precedentemente scollegati da Aptana Git

Connessione di EGit ai progetti git precedentemente scollegati da Aptana Git

Il Synchronize di Eclipse, uno dei miei strumenti preferiti del mio IDE preferito

Eclipse ha molte funzioni, ma una delle mie preferite e indipendenti dal VCS utilizzato (GIT, SVN, …) è la view Synchronize, che mostra l’elenco dei file modificati rispetto al repository (e all’origin nel caso del GIT) e da la possibilità di modificarli facilmente con una finestra di comparazione. Funzione fondamentale in un ambiente di sviluppo integrato degno di questo nome.
Titanium - Synchronize

Conclusioni

Si può usare un ide o qualunque editor di testo in combinazione con tool esterni, l’importante è avere sempre sotto mano tutte le funzioni di cui si ha bisogno. Titanium Studio per usare un eufemismo non è che sia proprio performante, ma è basato su quel mostro di configurabilità ed estendibilità che è Eclipse, conviene quindi sfruttare al meglio le sue peculiarità installando all’occorrenza ciò che manca.

Windows, git e bash

So che il titolo può sembrare strano, ma chi come me ha un pc con Windows a casa e un Mac al lavoro a volte sente la necessità di avere una shell “un po’ più Unix-like” anche sul pc, se non altro per evitare di tradurre script .sh in .bat, operazione che ha volte può risultare ardua.
Ci sono vari progetti che permettono di portare la shell dei sistemi Linux/Mac su Windows, MinGW e Cygwin su tutti, ma tutti noi abbiamo (o dovremmo avere) già installato git, quindi perché preocuparsi di installare dell’altro.

MinGW è infatti già incluso nell’installazione di git, e sebbene quando si apre il menù contestuale su una directory quel “Git bash” vicino a “Git init” e “Git gui” possa far pensare che per cliccarlo dobbiamo avere l’intenzione di usare Git, in realtà non è così.

Tasto destro del mouse e il gioco è fatto

Tasto destro del mouse e il gioco è fatto


Git bash apre semplicemente la shell bash sulla directory scelta e da lì possiamo dimenticarci dei comandi dos e utilizzare quelli che (dovremmo) conoscere bene.
La shell bash simulata su Windows grazie a MinGW

La shell bash simulata su Windows grazie a MinGW

Non sempre gli script .sh che ci portiamo dietro dal Mac girano al primo colpo, ma di solito qualche piccolo ritocco è sufficiente:

Script .sh per utilizzare ImageMagick su Windows

Script .sh per utilizzare ImageMagick su Windows


In questo esempio il comando convert di ImageMagick (popolare utility di manipolazione immagini) dava qualche problema a causa di un’omonimia con un altro comando già presente tra le variabili di sistema. È stato sufficiente esplicitare il percorso dell’eseguibile per far funzionare tutto a dovere.

Niente di trascendentale ma è comunque un piacere evitare inutili installazioni.