Premessa

Questo articolo è il primo di una serie dedicato a Git, un software per il controllo di versione open source. Man mano che i prossimi articoli saranno pronti verrano elencati, per facilità, di seguito. Verrà usato come esempio la creazione di un diario di scavo usando file testuali scritti in Markdown, perciò questa guida ha la doppia valenza di spiegare il funzionamento base di Git e contemporaneamete forire un esempio di buone pratiche per la redazione collaborativa di un possibile diario di scavo.

Introduzione

Git in parole semplice è un software progettato per il controllo delle versioni, ovvero un sistema che permette di tenere traccia di ogni modifica che viene fatta ai file digitali di un repository, tipicamente i file contenti il codice sorgente di un progetto software. In particolare si tratta di un sistema di controllo di versioni distribuito, il che significa che il singolo utente che ne fa uso ha una copia totale del database delle modifiche localmente nel proprio computer e non ha necessariamente bisogno di fare riferimento ad una copia principale su un software remoto, com'è il caso di altri progetti simili anche molto famosi nel passato, come Subversion e Mercurial.

Git è stato creto da Linus Torvalds, il creatore del kernel Linux nel 2005 ispirandosi ad altri progetti proprietari, proprio al fine di creare uno strumento per gestire lo sviluppo di Linux.

Git è alla base di progetti e piattaforme per lo sviluppo collaborativo estremamente diffuse quali GitHub, BitBucket, GitLab e Codeberg.

Ma Git può essere usato anche fuori da quello che può essere l'ambito ristretto dello sviluppo collaborativo e in generale è utilissimo in ogni ambito in qui è necessario tenere traccia delle modifiche nel tempo si un file o di un'intera cartella con la possibilita di “riavvolgere” il tempo e ritornare in un punto preciso nella storia passata del file, senza perdere la storia generale delle modifiche, passate e future.

Insomma, è posisbile fare a meno di creare file diversi con nomi fantasiosi pr tenere traccia delle modifiche nel tempo:

  • testo_finale
  • testo_finale2
  • testo_finale_rev
  • testo_finale_rev_corr
  • testo_finale_rev_corr2
  • testo_finale_rev_corr2b
  • testo_finale_rev_corr2b-2022-4-6
  • testo_finale_def
  • testo_finale_def-2

Prima di cominciare a dare uno sguardo in profondità, però, è necessaria qualche precisazione iniziale:

  • Git è stato progettato per essere usato da interfaccia a riga di commando, quindi è necessario disporre di terminale, anche se esistono varie soluzioni grafiche. Per semplicità questa guida farà riferimento solemente ai commando da terminale.
  • Git funziona con qualsiasi tipo di file, anche con file di grandi dimensioni attraverso specifiche estensioni. Bisogna però premettere che è sui file di testo che Git dà il meglio di se in efficienza e velocità, in quanto ci permette di visualizzare anche le singola righe di testo che sono cambiate. Dal momento che Git usa l'algoritmo crittografico SHA-1 (Secure Hash Algorithm 1) per calcolare l'impronta (hash) di ciascun file, potrebbe essere necessario del tempo di attesa per repository pesanti.

Concetti base

Git basa il suo funzinamento su alcuni concetti fondamentali, che è bene chiarire per potere procedere con la guida.

  • Con repository si intende l'insieme dei file che si sta sottoponendo a controllo di versione. Il concetto di repository coincide con quello della cartella superiore che contiene tutto il progetto
  • Con stage, scena, si intende uo stato intermedio delle nostre modifiche, la cui storia è “fotografata”, una istantanea (snapshot) dunque che non è stata ancora salvata nel registro principale delle modifiche.
  • Con commit si intende l'azione per cui un’istantanea, ovvero alcune modifiche che si trovano nello stage vengono registrate nel database principale.
  • Con remote si intende l'eventuale copia remota, su un server, della nostra repository. Possiamo usare Git senza necessità di avere una copia remota, ma se pianifichiamo di collaborare con altre persone, allora è necessario prevedere la possibilità di una copia remota che faccia da punto di riferimento per tutti i collaboratori.
  • Con branch, ramo, si intende una funzione fondamentale di Git, ovvero la possibilità di creare una linea di modifiche parallela a quella principale, dove uno o più collaboratori possono intervenire liberamente senza toccare il ramo principale. Una volta che si ritieneche le modifiche sul ramo secondario hanno raggiunto un grado di maturazione sufficiente, allora questo branch può essere unito (merge) a quello principale. Dopo questa unione, il branch secondario può essere cancellato. La documentazine di Git afferma che la i branch sono economici in termini di spazio e risorse e quindi viene raccomandato di fare un largo uso.
  • Con conflict si intende la situazione che si crea quando sullo stesso file sono reistrate modifiche da parte di più collaboratori e viene richiesta un’azione esplicitia per risolvere questo problema. I file di testo vengono annotati internamente, sehnalando le singole porzioni di testo che ciascun collaboratore ha modificato, dando la possibilità di risolvere il conflitto in maniera molto dettagliata.

Guida semplificata per esempi

Attenzione
In questa guida faremo uso del terminale per tutte le operazioni sia di Git che di interazione con il filesystem e con i singoli file. Naturalmente molte di queste operazioni possono essere svolte anche con altri strumenti, quali il gestore di cartelle del vostro sistema operativo e un editor di testi. Le operazioni che possono essere svolte con altri strumenti sono segnalata da (*)

Creazione del repository

Creiamo una cartelle che conterrà il nostro progetto*

mkdir diario-di-scavo

Ci spostiamo quindi dentro all nuova cartella*

cd diario-di-scavo

Avviamo Git per questa cartella, ovvero creiamo il repository

git init

E avremo come risposta qualcosa di simile:

Initialized empty Git repository in /qualche/percorso/diario-di-scavo/.git/

Abbiamo avviato la nostra prima repository Git, adesso aggiungiam qualche file. Per questa guida useremo dei file di testo scritti in Markdown un linguaggio di marcatura estremamente semmplice da scrivere e leggere.

Creiamo dentro la cartella un nuovo file chiamato index.md*

touch index.md

Apriamo il file e aggiungiamo del testo*

nano index.md

E scriviamo*

# Diario di scavo Questo repository contiene il diario di scavo diviso per settori e in ordine cronologico.

Poi salviamo e chiudiamo il file premendo ctr+x e rispondendo y alla domanda se vogliamo salvare o meno, poi invio, confermando il nome del file.

Abbiamo aggiunto un nuovo file, ma Git ancora non ha salvato nel proprio database queste modifiche. Git non traccia le modifiche in maniera automatica e dobbiamo essre sempre noi, in maniera esplicita, ad addiungere ciascuna modifica alla sua storia delle modifiche.

In ogni momento è possibile controllare lo stato del nostro repository con git status, anche in questa fase iniziale quando ancora non stiamo tracciando alcun file:

git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) index.md nothing added to commit but untracked files present (use "git add" to track)

Il report ci informa che ci troviamo sul ramo master (On branch master). Anche se non abbiamo fornito alcuna informazione su come si intendeva organizzare il repository, Git crea per noi un branch iniziale e principale che chiama master.
Inoltre il report ci informa che non ci sono ancora commit disponibili (No commits yet).
Successivamente ci fornisce una lista dei file presenti nella cartella che non sono ancora stati segnalati a Git per il traccamento, in questo caso si tratta del file index.md.
Il commando ci fornisce, infine, anche qualche suggerimento per come proseguire a tracciare i file.

Questa azione si articola in due passaggi: aggiungere ciascuno dei file modificati allo stage (v. sopra i Concetti base) creando di fatto un'istantanea del nostro repository e successicamente aggiungere questa istantanea al database di Git, faccendo un commit (v. sopra i Concetti base).

git add index.md

add aggiunge un file all'istantanea, indice o stage. Possono essere elencati di seguito al commando singolarmente i singoli file (come abbiamo fatto per index.md) oppure può essere usato il carattere * per intendere tutti i file modificati.

Se invece si vuole togliere un file specifico dallo stage allora è disponibile il commando git reset -- <nome file>. A scopo puramente esemplificativo, il commando per togliere index.md dallo stage sarebbe (per ora non lo dobbiamo eseguire):

git reset -- index.md

Finalmente per aggiungere l'istantanea, al database di Git dobbiamo usare il commando commit che richiede l'aggiunta di un messaggio testuale. Il consiglio è quello di descrivere in questo messaggio la modifica effettuata nella maniera più precisa e concisa possibile, in maniera di fornire infomrazioni utili ai nostri collaboratori (o al nostro noi del futuro). Ecco allora come potrebbe apparire il nostro primo commando di commit:

git commit -m "Primo commit: aggiunto index.md"

Il programma ci darà come risposta un report simile al seguente

[master (root-commit) c5bea7e] Primo commit: aggiunto index.md 1 file changed, 3 insertions(+) create mode 100644 index.md

Nello specifico c5bea7e sono i primi 7 caratteri dello hash o impronta del commit che servono da identificativo. Per Git questo è il nome con il quale ci dobbiamo riferire a questo commit ogni volta che abbiamo necessità.
Il report prosegue dicendoci chè e stato mofificato 1 solo file (1 file changed) e nello specifico sono state inserite 3 nuove righe (3 insertions(+)).

Ogni volta che si introduce qualche nuova modifica dei file sottoposti al versionamento, sarà possibile aggiungere queste modifiche allo storico generale con i commandi git add <nome file> e git commit -m "Messagio di commit>.