Nella precedente lezione abbiamo visto brevemente come lavorare con i repository remoti. Abbiamo mostrato come usare i comandi git push e git fetch per transferire i commit dei branch presenti nel repository locale in un repository remoto e viceversa. Nel corso di questa guida abbiamo avuto modo di testare le diverse funzionalità messe a disposizione da Git il quale fornisce un cospicuo numero di comandi ma lascia grande libertà nel loro utilizzo.
Quando si lavora in team è però importante stabilire un flusso di lavoro (workflow) che permetta di garantire degli standard qualitativi del codice scritto e consenta di ottimizzare il processo di collaborazione. Stabilendo a priori delle regole e delle linee guida da seguire nella realizzazione di un progetto, è possibile collaborare con gli altri membri di un team in maniera più efficiente e produttiva.
Nonostante Git sia un software per il controllo di versione distribuito, spesso si decide di usare un repository remoto principale nel quale confluiscono, attraverso diversi meccanismi forniti da Git o dalle piattaforme di hosting di repository adoperate, le diverse funzionalità sviluppate localmente dai singoli membri di un team.
Alcuni esempi di flusso di lavoro
Non esiste un flusso di lavoro unico in Git. È possibile creare un proprio workflow personalizzato a seconda delle esigenze e delle modalità di lavoro di ciascun team. Diverse aziende e team hanno sviluppato un proprio workflow. Nel resto di questa lezione descriveremo in maniera concisa due diversi workflow. Il primo è quello usato da Github, il secondo è quello ideato e descritto da Vincent Driessen sul proprio blog, in quello che ormai è uno degli articoli più popolari in merito a Git.
Flusso di lavoro usato da Github
Iniziamo a parlare del flusso di lavoro preferito da Github che è stato scelto per velocizzare e ottimizzare il processo di frequenti pubblicazioni di nuove funzionalità.
In sostanza viene usato il branch Master come branch stabile. I commit che si trovano sul branch master contengono una versione del software pronta per essere messa in produzione. (resa pubblica) Ogni volta che si vuole lavorare a una nuova funzionalità, viene creato un nuovo branch a partire dal branch master. Per il nuovo branch creato viene scelto un nome che renda chiaro e esplicito il tipo di funzionalità a cui si sta lavorando. Vengono quindi eseguiti i commit sul nuovo branch creato che vengono poi inviati regolarmente all’omonimo branch remoto. Nel momento in cui si ritiene che la funzionalità sviluppata è pronta o semplicemente si ha bisogno dell’aiuto di un altro membro del team, viene effettuta una ‘Pull Request’. È possibile integrare le modifiche apportate nel branch master solo dopo che sia stato verificato che tutto funzioni correttamente e sono stati rispettati gli standard e le linee guida stabilite all’inizio del progetto. Viene quindi effettuato il merge nel branch master e si è pronti per il rilascio pubblico della nuova funzionalità. Al termine di questo processo è possibile rimuovere il branch creato in precedenza per lo sviluppo della nuova funzionalità. Lo stesso sistema viene usato anche in caso di risoluzione di bug.
Come detto, è un flusso di lavoro abbastanza lineare che predilige la semplicità al fine di velocizzare il meccanismo di rilascio frequente di nuove versioni.
Per maggiori informazioni potete consultare la guida illustrata pubblicata sul sito di Github.
Gitflow
Quello che viene definito Gitflow è probabilmente uno dei workflow più conosciuti e diffusi. Venne presentato per la prima volta da Vincent Driessen sul suo blog nel 2010.
Si tratta di un flusso di lavoro che prevede l’uso di un repository principale a cui vengono inviati i nuovi commit dai membri del team che però possono scambiarsi informazioni direttamente se necessario. Si tratta quindi di un modello ibrido che presenta caratteristiche tipiche di un sistema centralizzato e di uno decentralizzato. Vengono quindi definiti diversi branch, ognuno con uno scopo preciso così come è possibile vedere dall’immagine riportata in alto. (Si tratta dell’immagine pubblicata originariamente da Driessen) È possibile suddividere i branch in due categorie: branch stabili (ovvero branch che presentano una versione del software pronta per essere rilasciata) come master, i branch hotfix e i diversi branch usati per ogni release e i branch instabili (branch in cui le diverse funzionalità sono in fase di sviluppo), ovvero il branch develop e i branch creati per ogni feature che si vuole sviluppare. A partire dal branch develop si dirama un branch per ogni nuova funzionalità sviluppata. Questi vengono poi reintegrati nel branch di partenza quando la nuova funzionalità ha superato tutte le verifiche e i test necessari. Il branch develop viene incorporato in un diverso branch per ogni nuova release. Su quest’ultimo vengono corretti bug minori e quando si è pronti per il rilascio di una nuova versione si effettua l’operazione di merge nel branch master. Da ciascun branch release è possibile incorporare le modifiche nuovamente nel branch develop. Ciò avviene in particolare dopo la risoluzione di bug. Il branch master contiene le versioni pronte per essere rilasciate. I branch hotfix vengono usati per risolvere bug critici di versioni già rilasciate. Tali branch confluiscono nuovamente nel branch master ma devono essere anche inclusi nel branch develop attraverso l’operazione di merging.
Anche in questo caso, abbiamo descritto il workflow in maniera superficiale. Se volete approfondire l’argomento potete trovare una descrizione dettagliata nel post originale. È inoltre possibile trovare su Github il repository contente gli strumenti, estensioni e comandi di Git per chi volesse adottare questo specifico workflow.
Scegliere un proprio flusso di lavoro in Git
Nello scegliere un proprio workflow è opportuno verificare le esigenze e la filosofia di lavoro del team. Non esiste una soluzione univoca, ma si può partire da dei flussi di lavoro già utilizzati e testati e riadattarli alle proprie necessità. Può comunque risultare conveniente usare un repository principale ospitato magari su una delle piattaforme già elencate nelle precedenti lezioni e usare il meccanismo delle Pull Request per consentire a ciascun membro del team di lavorare localmente a una certa funzione dopo aver creato un nuovo branch a partire da un branch stabile che può essere usato per il rilascio di nuove versioni. Quando si lavora con repository condivisi è comunque opportuno non modificare la storia dei branch comuni al fine di evitare ambiguità e difficoltà di diversa natura. Per questo motivo comandi che modificano la storia di un branch come git rebase vanno usati solo su branch locali.
Conclusioni
Dopo aver visto alcuni esempi di flussi di lavoro in Git, nella prossima e ultima lezione della guida parleremo di un’altra utile funzionalità di Git, ovvero dei Git hook, script che vengono eseguiti al verificarsi di determinati eventi.