Primi passi con Git

Qualche tempo fa avevamo dato uno sguardo dall’alto a Git e alle sue caratteristiche più convincenti.

In questo post vediamo come installare Git sulla nostra macchina di sviluppo e come iniziare a gestire il versioning dei nostri progetti.

Installare Git

Il primo passo da fare è procurarsi il giusto pacchetto d’installazione. Dal sito ufficiale potete scegliere quello corrispondente al vostro sistema operativo.

La procedura d’installazione in ambiente Windows è piuttosto semplice. Dopo aver scaricato il file .exe, basterà farsi guidare dal classico wizard.

Se state lavorando su Linux Ubuntu, non avrete nemmeno la necessità di scaricare il pacchetto d’installazione dal sito; vi basterà invece sfruttare l’Advanced Package Tool (APT):

sudo apt-get install git

E il gioco è fatto!

Nota Per lavorare con Git avremo bisogno di usare la console di comando, per cui, se state lavorando su Linux rispolverate la vostre conoscenze di Bash, mentre se siete affezionati a Windows procuratevi qualche manuale di DOS (è richiesto solo qualche comando basilare, quindi non preoccupatevi).

Creare un repository

Ora viene il bello. Per cominciare a lavorare con Git abbiamo bisogno di un repository che funga da contenitore per il nostro progetto.

In realtà un repository non è altro che una cartella in cui includeremo tutti i file e le eventuali sub-directory associate al progetto.

Inizializzare un nuovo repository è semplicissimo: creiamo una nuova cartella e posizioniamoci su di essa usando linea di comando, ad esempio:

mkdir new-project
cd new-project/

A questo, per trasformare la nostra semplice cartella in un repository vero e proprio, lanciamo il comando:

git init

Se non ci sono intoppi, otterremo come risultato un messaggio del genere:

Inizializzato un repository Git in /path/to/repository/new-project/.git/

Come spiegato nel messaggio, l’inizializzazione genera una directory .git/ che, a tutti gli effetti, conterrà tutta la storia del repository, includendo informazioni su commit, branch e tag.

Ora, per capire meglio come funziona Git è importante comprendere che ogni repository si basa su tre concetti chiave:

  • la working directory, ovvero la cartella locale che contiene i file di progetto;
  • la staging area o index, ovvero l’indice dei file da “congelare” nella prossima revisione (commit);
  • il puntatore a HEAD, cioè all’ultima revisione presente nel repository.

Vediamo come funzionano questi elementi…

Aggiungere e rimuovere file

Una volta creato il nostro repository possiamo iniziare ad aggiungere file al progetto.

Prima di poter effettuare un nuovo commit, però, dobbiamo indicare a Git quali file includere nella prossima revisione. Per farlo dobbiamo aggiungere questi file all’index utilizzando il comando add:

git add .

Il comando riportato permette di aggiungere alla staging area tutti i file presenti nella working directory. Ovviamente possiamo aggiungere anche singoli file usando il comando in questo modo:

git add file1.txt

Per verificare quali file sono presenti nella staging area, invece, possiamo utilizzare il comando:

git status

Che restituirà qualcosa del genere:

Sul branch master

Commit iniziale

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   file1.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	file2.txt

Al di là del mix di lingue… notiamo che il comando ci restituisce un quadro della situazione attuale all’interno del nostro repository. Abbiamo un file,file1.txt, pronto per il commit e un secondo file,file2.txt, untracked, ovvero “sconosciuto” al repository e che non prenderà parte alla prossima revisione.

Git ci spiega inoltre che, se desideriamo, possiamo rimuovere file dalla staging area con il comando:

git rm --cached <file>...

Nota L’opzione --cached permette di rimuovere i file dall’indice, senza eliminarli fisicamente dalla working directory. Fate quindi attenzione a non dimenticare questa opzione se non volete effettivamente eliminare il vostro lavoro.

Il file .gitignore

Esiste un file “speciale” che possiamo sfruttare per indicare quali file, all’interno di un repository, vogliamo ignorare intenzionalmente.

Questo file si chiama .gitignore e include i file e le directory di progetto che rimarranno nello stato untracked anche quando utilizzeremo il comando git add ., visto precedentemente.

Vediamo un esempio. Supponiamo di creare un file .gitignore vuoto nel nostro repository e di lanciare il comando git status. Se ricordate bene, nel precedente commit non avevamo incluso il file file2.txt, infatti lo ritroviamo esattamente dove l’avevamo lasciato insieme al nuovo file appena creato:

Sul branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	.gitignore
	file2.txt

nothing added to commit but untracked files present (use "git add" to track)

Tutto chiaro. A questo punto, apriamo il file .gitignore con un editor di testo e nella prima riga aggiungiamo:

file2.txt

In questo modo stiamo dicendo a Git di non tenere traccia dei cambiamenti avvenuti nel file2.txt e di escluderlo da eventuali add successivi. Se ora proviamo a verificare nuovamente lo status, otterremo qualcosa di simile:

Sul branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

	.gitignore

nothing added to commit but untracked files present (use "git add" to track)

Come vedete, file2.txt è diventato “invisibile” per Git, per cui possiamo essere sicuri che questo file non venga accidentalmente incluso in una prossima revisione del nostro progetto.

In ogni caso, se per qualche motivo avessimo bisogno di aggiungere un file che è stato indicato nel .gitignore, possiamo comunque forzare l’add nella staging area usando l’attributo -f:

git add -f file2.txt

Primo commit

Siamo pronti a creare la nostra prima revisione. Per farlo dobbiamo usare il comando commit:

git commit -m "Primo commit"

È importante notare che in Git, ogni commit deve essere necessariamente accompagnato da un messaggio descrittivo. Per specificarne uno usiamo l’attributo -m.

Benché non ci siano regole ferree riguardo la formulazione dei messaggi associati alle revisioni, esistono alcune linee guida comunemente seguite, soprattutto nell’ambito di progetti open source.

Ad esempio, convenzionalmente, ogni commit dovrebbe essere descritto mediante un ordine che chiarisca quali modifiche devono essere apportate al progetto in quella specifica revisione. Qualche indicazione a riguardo la trovate in questo interessante articolo pubblicato su Medium.

L’esecuzione di un commit, congela lo stato dei file presenti nella staging area in una revisione, dopodiché l’indice torna “pulito”, pronto per un nuovo commit.

Ogni revisione è identificata da un hash generato tramite l’algoritmo SHA-1. Per visualizzare lo storico dei commit del nostro repository possiamo eseguire questo comando:

git log

Che in questo caso mostrerà un solo risultato:

commit 83a097bea778bc9bbb417485a81cc7c9e8cf2911
Author: David <[email protected]>
Date:   Sun Feb 4 19:22:22 2018 +0100

    Primo commit

Prima abbiamo parlato di HEAD, ovvero del puntatore all’ultimo commit effettuato. Possiamo fare una verifica utilizzando il comando show:

git show HEAD

Che restituisce:

commit 83a097bea778bc9bbb417485a81cc7c9e8cf2911
Author: David <[email protected]>
Date:   Sun Feb 4 19:22:22 2018 +0100

    Primo commit

diff --git a/file1.txt b/file1.txt
new file mode 100644
index 0000000..e69de29

In conclusione

Abbiamo esaminato alcuni dei comandi principali di Git per cominciare a gestire i nostri progetti con questo sistema di controllo di revisione.

Ovviamente c’è molto più di questo: in uno dei prossimi post parleremo di branching e di come implementare un flusso di lavoro che favorisca produttività e collaborazione.

A presto,

David