Il problema della gestione delle modifiche è da considerarsi di carattere generale, anche in assenza dei sistemi di controllo di versioni, come già accennato nel precedente articolo sugli artefatti . Poiché tale gestione può seguire logiche diverse, anche i software di versioning presentano delle peculiarità che li rendono diversi l'uno dafgli altri; tutti, però, hanno in comune le nozioni e le operazioni che sono alla base delle attività di controllo di versione.
Nel seguito dell’articolo faremo una rapida trattazione di queste nozioni e operazioni senza avere la pretesa di renderla esaustiva, ma con l’intento di introdurre i principali meccanismi di funzionamento di un programma di tale genere.
Commit: è l’operazione con la quale vengono archiviate nella base dati del software di controllo le modifiche effettuate su un artefatto. Solitamente, l’operazione di commit prevede la stesura di una breve nota per consentire a chi accede alla versione di conoscere la natura e lo scopo del commit. Le note di versione possono essere considerate come la traduzione delle modifiche tecniche in un linguaggio più vicino alla tipologia di utente a cui sono destinate.
Update: è l’operazione inversa al commit e consiste nel recupare le modifiche apportate da altri ad un artefatto. In pratica, l’update comporta l’applicazione delle modifiche alla propria copia locale del deliverable così da poter operare su una copia aggiornata. Solitamente si ricorre a questa operazione con una certa frequenza, in quanto permette di visionare l’operato degli altri e di verificare la risoluzione di un bug nel caso se ne individuasse uno.
Repository: è il database nel quale vengono memorizzate le modifiche e vengono generate tutte le informazioni di revisione degli artefatti. I database possono essere sia centralizzati che distribuiti. Nel primo caso tutti gli utilizzatori fanno capo ad un unico repository che provvederà a memorizzare tutte le informazioni sulle revisioni; nel secondo caso, ogni utilizzatore ha il proprio repository che il software di versioning provvederà a fondere con quelli degli altri utilizzatori seguendo delle regole di dipendenza tra le modifiche. Come sempre, la scelta del repository centralizzato o distribuito dipende fortemente dal contesto del suo utilizzo e non determina la qualità del software utilizzato.
Checkout: è l’operazione con la quale si recupera il materiale presente in un repository. In pratica, equivale a creare una “copia di lavoro” locale di un progetto sottoposto a controllo di versione. La copia di lavoro locale rientra a tutti gli effetti nel meccanismo di controllo di versione e può essere a sua volta soggetta a “commit” per registrare nuove versioni. Il materiale locale recuperato da un’operazione di checkout contiene la struttura di file prodotta fino a quel momento ed i metadati necessari per le attività di controllo.
Revisione: è la concretizzazione (o istanza) di un artefatto in un determinato istante nello storico che rappresenta la sua evoluzione. Ad esempio, eseguendo un commit sul documento X a questo verrà assegnata la versione 1. Il documento X potrà essere recuperato da un altro utente mediante update, che potrà successivamente rieseguire un commit sullo stesso documento, generando la versione 2. Così facendo il documento X avrà “n” versioni, ognuna delle quali recuperabili tramite il sistema di versioning.
Diff: è la rappresentazione delle modifiche effettuate su un artefatto. In pratica è il risultato di un confronto fra due versioni; ad esempio in un documento mostra quali righe sono state cambiate ed in che modo.
Tag: è l’identificativo di un insieme di file ad una specifica revisione. I tag sono molto utili per identificare la parte di progetto che presenta delle modifiche “interessanti”. Ad esempio, nel caso di rilascio di una versione, un tag può rappresentare l’insieme dei file che hanno subito variazioni.
Branch: è una copia indipendente (o ramo) del progetto originario che segue una differente linea di sviluppo. Scopo principale di un branch è quello di evitare che le modifiche applicate alla nuova linea di sviluppo possano interferire con quelle del progetto originario. Solitamente lo stesso progetto originario è un branch chiamato “master” o “linea principale”. L’utilizzo dei rami di sviluppo è utilizzato per lo più per sviluppi che prevedono delle variazioni funzionali rispetto alla linea principale (ad esempio, per implementazioni sperimentali).
Merge: è l’operazione attraverso la quale si fanno confluire due branch in un unico ramo di sviluppo. Praticamente equivale a riportare in un altro le modifiche applicate ad un altro ramo .
Merge di file: è l’operazione che comporta l’unione delle modifiche apportate allo stesso file da due operatori differenti. Tutti i moderni sistemi di controllo versione sono in grado di valutare le differenze tra due file e, in assenza di conflitti, di effettuare l’unione automatica con la creazione di un unico file
Conflitto: è l’effetto che si produce quando due modifiche riguardano la stessa parte di codice. I conflitti sono molto comuni in un ambito di lavoro di gruppo e possono essere risolti solo manualmente da un operatore che è in grado di sciogliere le ambiguità emerse.
Blocco: è l’operazione che vincola le modifiche ad un file finchè non viene chiusa da chi l’ha avviata. Non tutti i sistemi di versioning la utilizzano perché tale pratica vincola lo sviluppo parallelo e pertanto risulta scarsamente utilizzata. In alcuni casi il concetto di blocco è utilizzato solo in contesti particolari, come quello del commit, per garantire l’atomicità delle azioni.
Autore
Vincenzo Tirelli
Innovation Manager – Senior Software Designer
Ho iniziato a collaborare con la SNAP a partire dal 2007, in qualità di ...