[GIT] Il versionamento distribuito con GIT ed un efficiente modello di branching

Vi scrivo oggi di un interessante modello di versionamento che si basa sul famosissimo GIT, repo usata ai primordi per la distribuzione del kernel Linux e negli ultimi tempi come maturo e completo sistema di versioning distribuito. GIT ha attirato gran parte degli sviluppatori di vari linguaggi, tanto da diventare più utilizzato di SVN.

Per la configurazione di GIT e alcune nozioni di base, vi rimando all’ottimo articolo “CVS, SVN e GIT!“.
Per approfondire, il miglior riferimento è il freebook online: http://git-scm.com/book
Carina è anche la semplice guida “git – the simple guide
Personalmente uso il servizio online di GITHUB per versionare i miei progetti. Anche se mi sto trovando molto bene con Assembla, invece, per versionare piccoli progetti su repo SVN. Ho utilizzato Mercurial, ma ho avuto non pochi problemi di compatibilità/bug con vari plugin HG. Se volete versionare su una repo GIT, vi consiglio di installare i client SmartGIT, SourceTree o Tortoise (su Mac, ma alcuni anche per Windows). Su XCode in Mac, il plugin di GIT è già configurato e potete sceglierlo come versionatore del vostro progetto.
Ora, qual è il punto di forza di GIT? Sicuramente la decentralizzazione del codice sorgente. Nell’articolo che vi linko, si enumerano i punti a favore di GIT rispetto a sistemi centralizzati di controllo versione come SubversionWhy you should switch from SubVersione to GIT
In sintesi, come già detto, GIT ha il vantaggio di essere una repo distribuita. Invece di lanciare il comando “svn checkout (url)“, che preleva l’ultima versione della repository di progetto, su GIT si lancia il comando “git clone (url)”  che copia-clona l’intera history di progetto. Ciò significa che il clone non intacca il progetto originale presente sulla repo e uno sviluppatore può autonomamente lavorare su una sua copia, in modalità offline.
Con questo nuovo paradigma è possibile committare in una repository locale anche in assenza di connessione alla rete, cosa che invece non era possibile con SVN, visto che il committ viene fatto interamente sulla repo remota.
Altro vantaggio implicito di questo modello è che il workflow non ha un “single point of failure“. In GIT ciascun membro può pushare su qualsiasi altro server se quello centrale viene corrotto, così che altri membri possono accedere in SSH e ripristinare la working copy in pochi minuti.
Grazie al meccanismo di pull e push, la sincronizzazione tra le repo GIT di ciascun membro è alquanto efficiente. Il meccanismo distribuito permette di creare tante repo private (locali) e sincronizzarle con quelle pubbliche. Un integration manager può pullare tutte le copie pubbliche su un unico “gold repository”, dove ci sarà la versione stabile da deployare in produzione.

 

Una feature ben fatta di GIT è quella che permette il merging tra i branch. Ogni membro del team può creare la propria “feature” su un branch separato e committare/pullare il tutto sul branch condiviso (modello che approfondiremo in seguito).
Quando viene creato un branch in GIT, si può facilmente switchare a quello nuovo per iniziare a svilupparci sopra. I branch si possono riaprire per fixare bug, inserire nuovo codice e poi mergiare il tutto sulla “mainline work“. L’operazione di merge genera pochissimi conflitti sui file.
Esiste una vera e propria “area di sosta” dei file, detta staging area, che non è altro che una cache locale in cui si trovano le modifiche del codice prima del commit. Questa è molto utile per avere una peer-review del lavoro fatto. E’ possibile committare i singoli changeset in seguito. GIT mantiene traccia di “parti di file” (stage files) come delta delle modifiche apportate al codice, che si possono committare selettivamente (patch staging).
Queste modifiche, logicamente separate, possono essere committate separatamente per una facile review del progetto e tale feature è detta cherry-pickable.
Passiamo ora alla descrizione di un efficiente modello di branch di GIT, prendendo come riferimento l’articolo “A successful GIT branching model“.

 

In questo modello esiste una repo denominata “origin” che è quella centrale in cui tutti i membri del team pullano e pushano una versione stabile o condivisa delle modifiche.

 

 

Main branches. La repo centrale contiene due main branches che vivono per tutta la durata del progetto e che si chiamano “master” e “develop“.

 

Il branch origin/master conterrà il codice che verrà messo in produzione. Il branch origin/develop è quello dove vengono pushate tutte le modifiche di sviluppo di ciascun membro del team di sviluppo e che viene continuamente aggiornato fino a quando non si è prodotta una versione stabile da mettere in produzione. È anche detto “branch di integrazione” delle repo distribuite tra i vari sviluppatori.
Quando si reputa stabile, il codice su origin/develop viene mergiato su origin/master.
Supporting branches.
Oltre ai branch “principali”, esistono altre tipologie di branch di vita limitata (detti branch di supporto) che si classificano come segue:
  • Feature branches
  • Release branches
  • Hotfix branches

Feature branches. Si stacca (branch off) da develop e si mergia sempre in esso. Si può chiamare in qualsiasi modo tranne che master, develop, release-* o hotfix-*.
Si chiama anche “topic branches” e contiene gli sviluppi di una features o funzionalità logica del progetto.
Per creare un nuovo feature branch facendo il branch off da develop:
$ git checkout -b myfeature develop
Switched to a new branch "myfeature"
 Per mergiare la feature su develop quando è stata ultimata:
$ git checkout develop
#Switched to branch 'develop'
$ git merge --no-ff myfeature
#Updating ea1b82a..05e9557
#(Summary of changes)
$ git branch -d myfeature
#Deleted branch myfeature (was 05e9557).
$ git push origin develop
Il flag –no-ff (dove “ff” sta per “fast-forward”) evita di “confondere” il codice della features nella mainline di progetto. Molto utile nel caso si voglia ricostruire la storia dei commit.

 

Release branches. Il branch off qui avviene da develop e si può mergiare sia su master che su develop. La naming convention è release-*. Questo tipo di branch supporta la preparazione per un nuovo rilascio in produzione. Infatti, mette a disposizione un insieme di metatag utili per etichettare la build version, la data di rilascio, ecc.
Per creare un release branch da develop, supponendo di stare alla versione 1.1.5 in produzione e di voler passare alla 1.2:
$ git checkout -b release-1.2 develop
#Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
#Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
#[release-1.2 74d9424] Bumped version number to 1.2
#1 files changed, 1 insertions(+), 1 deletions(-)
 A questo punto, possiamo mergiare il release branch sul master:
$ git checkout master
#Switched to branch 'master'
$ git merge --no-ff release-1.2
#Merge made by recursive.
#(Summary of changes)
$ git tag -a 1.2
Per prendere le modifiche fatte nel release branch e portarle in develop:
$ git checkout develop
#Switched to branch 'develop'
$ git merge --no-ff release-1.2
#Merge made by recursive.
#(Summary of changes)
Infine, per rimuovere il release branch:
$ git branch -d release-1.2
#Deleted branch release-1.2 (was ff452fe).

 

Hotfix branches. Il branch off si fa da master e si mergia sia in master che in develop. Il naming convention è hotfix-*.
È come il release branch ma viene creato dopo che si ha uno stato indesiderato in produzione, come un bug critico da risolvere immediatamente. A tal scopo di fa un branch off dal corrispondente tag del master che marca la versione in produzione.

Supponendo di avere in produzione la versione 1.2 su cui è avvenuto un severe bug, un hotfix branch si crea così:

 

$ git checkout -b hotfix-1.2.1 master
#Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
#Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
#[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
#1 files changed, 1 insertions(+), 1 deletions(-)
 I commit delle modifiche per la correzione del bug si effettuano su tale hotfix:
$ git commit -m "Fixed severe production problem"
#[hotfix-1.2.1 abbe5d6] Fixed severe production problem
#5 files changed, 32 insertions(+), 17 deletions(-)
A fine correzione, il merge sul master si fa come un release branch:
$ git checkout master
#Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
#Merge made by recursive.
#(Summary of changes)
$ git tag -a 1.2.1
E per allineare il develop con il bugfix:
$ git checkout develop
#Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
#Merge made by recursive.
#(Summary of changes)
Unica eccezione si ha quando la fix riguarda un release branch esistente. In tal caso, l’hotfix va mergiato su tale release, invece che su develop.
Per rimuovere l’ hotfix branch:
$ git branch -d hotfix-1.2.1
#Deleted branch hotfix-1.2.1 (was abbe5d6).

L’Italia e i principi fondamentali di Internet: la Rete come strumento di democrazia

Finalmente, anche una Italia propositiva sulla promulgazione della “carta” dei principi fondamentali di Internet. E’ partita dal 18 settembre la Consultazione pubblica a cui vi invito a partecipare. Affrettatevi perché si chiuderà il giorno 1 novembre 2012

Il Ministero per l’Università e la ricerca vuole “arricchire e migliorare il documento che riassume la posizione italiana sui principi fondamentali di Internet” da portare all’Internet Governance Forum (IGF) di Baku. Tutti i cittadini possono contribuire al dibattito sui cinque temi tradizionali del Forum ri-etichettati per l’occasione: principi generali, cittadinanza in rete, consumatori e utenti della rete, produzione e circolazione dei contenuti e sicurezza in rete.

Ecco i link degli articoli tratti da LaRepubblica.it:

Vi allego l’estratto del documento ufficiale del MIUR, che potete scaricare anche da qui:

La posizione italiana sui principi fondamentali di Internet
Continua la lettura

[CleanCode] Il test di Joel: 12 domande per migliorare il tuo codice

Hai mai sentito parlare del SEMA? Si tratta di un sistema, piuttosto esoterico a dire il vero, per misurare l’abilità di un team di sviluppo di software. No, aspetta! Non cercare di informarti sul SEMA! Ti ci vorrebbero almeno sei anni solo per cominciare a capire di che si tratta. Così ho preferito inventarmi il mio personalissimo, poco scientifico e inadeguato test per la valutazione della qualità di un team di sviluppo software. La cosa interessante di questo test è che richiede al massimo tre minuti, così con tutto il tempo che puoi risparmiare puoi iscriverti a un corso di medicina.

Il test di Joel

  1. Utilizzi un prodotto per il controllo del versioning dei file?
  2. Riesci a compilare un intero programma con un solo comando?
  3. Crei almeno una build al giorno?
  4. Hai un sistema di gestione dei bug?
  5. Sei solito risolvere i bug prima di scrivere del nuovo codice?
  6. Hai un programma di sviluppo aggiornato?
  7. Hai un documento di specifiche?
  8. I tuoi programmatori lavorano in un ambiente tranquillo?
  9. Ti servi dei migliori prodotti presenti sul mercato?
  10. Hai dei tester nel tuo team?
  11. Durante il colloquio, fai scrivere del codice a chi si presenta per far parte del tuo team?
  12. Fai eseguire dei test di usabilità a sorpresa?

La cosa interessante del Test di Joel, è che ti permette facilmente di dare una risposta a ogni domanda, sia essa sì o no. Non hai bisogno di immaginarti il numero di righe di codice che sei in grado di produrre al giorno, o il numero medio di bug che riesci a chiudere. Basta che assegni al tuo team un punto per ogni “sì”. Purtroppo, la cosa brutta di questo test è che non dovresti assolutamente utilizzarlo, in modo da evitare possibili svenimenti.

Un punteggio complessivo di 12 rappresenta la perfezione, 11 è invece tollerabile, ma realizza 10 o meno e stai certo che andrai incontro a problemi piuttosto seri.
La verità, purtroppo, è che la maggior parte dei team di progetto realizza punteggi compresi tra 2 e 3 e ha bisogno veramente di un grande supporto, dato che compagnie come Microsoft viaggiano a ritmi da 12 a botta.

È ovvio che quelli elencati non sono gli unici fattori che concorrono al successo o al fallimento di un team: per esempio, qualora avessi a disposizione un team eccezionale per la realizzazione di un software che comunque non interessa a nessuno, bé la gente non lo acquisterebbe lo stesso.
Ed è anche possibile che un team di imbranati, incapace a rispondere affermativamente a una sola delle mie domande, riesca comunque a produrre un software fantastico, capace di cambiare il mondo. In ogni modo, non considerando questi fattori esterni, è un dato di fatto che se ottieni un 12 secco, potrai contare su un team disciplinato e capace di consegnare il prodotto in qualunque momento.

Continua la lettura

[iOS] Inserire le mappe e la localizzazione con MapKit e CoreLocation Framework

Sicuramente sapete che Apple è arrivata ai ferri corti, da un bel pezzo, con Google e ha comunicato di non includere neanche YouTube come app preinstallata sul melafonino:

Addirittura Apple ha lanciato la sfida a Google Maps con un’app che dà anche informazioni sul traffico e fornisce un sistema di navigazione in 3D, che dovrebbe uscire su iOS 6.

Tuttavia, per chi volesse ad inserire una mappa o indicazioni di geolocalizzazione nelle proprie app, in attesa delle API ufficiali del nuovo sistema di navigazione Apple succitato, vi riporto un esempio su come utilizzare MapKit e CoreLocation Framework.

Nel progetto di esempio (che vi allego alla fine di questo articolo), trovate una view con una mappa centrata su un punto GPS (latitudine, longitudine) definito (e segnalato da un marker). Vi è possibilità di definire diverse modalità di visualizzazioni della mappa (normale, satellitare, ibrida) e la possibilità di segnalare il percorso (a piedi o in macchina) dal punto GPS in cui si trova il vostro device e il luogo di arrivo preimpostato. Inoltre, viene calcolato anche il tempo stimato e i metri da percorrere (a piedi o in macchina) dall’origine alla destinazione.

Ecco la “lista della spesa” delle librerie/framework che ci servono:

  • RegexKitLite: è una libreria di supporto che permette di utilizzare le espressioni regolari (regex) – Lightweight Objective-C Regular Expressions for Mac OS X using the ICU Library
  • MapKit Framework: fornisce le API per il download delle mappe, lo zoom e l’inserimento delle annotazioni (marker)
  • CoreLocation Framework: permette di determinare la posizione GPS corrente e la direzione spaziale del device

[iOS] Un video player nelle nostre app con il MediaPlayer framework e Google Data Library

Vi spiego come realizzare un video player da inserire nelle nostre app che vi permetta di visualizzare i video in vari formati (mp4 e avi, i formati che ho provato io) oppure di prelevarli da un canale youtube e listarli in una UITableView. Quindi, divido questo tutorial in due parti:

Alla fine di questo tutorial, trovate in allegato l’archivio con il progetto di esempio che verrà qui spiegato, con una tab bar application con due viste in cui vengono realizzati i due video player di esempio.

Continua la lettura