In questa lezione della nostra guida vedremo come iniziare a usare Git. Impareremo quindi alcuni dei comandi base e i concetti fondamentali che ci aiuteranno a comprendere meglio il funzionamento di Git.
Inizializzare un repository Git
Per inizializzare un repository Git, basta lanciare il comando git init all’interno della cartella in cui sono presenti i file di cui vogliamo tenere traccia. Nell’esempio che segue, creiamo quindi una nuova cartella prova_git con all’interno un semplice file di testo e delle sottocartelle che possono contenere a loro volta degli altri file con estensione .txt. Riportiamo sotto il contenuto della directory.
$ tree
.
├── africa
├── antartide
├── asia
├── europa
├── mete_turistiche_dicembre.txt
├── nord_america
├── oceania
└── sud_america
7 directories, 1 file
Procediamo eseguendo il comando git init all’interno della directory prova_git e otteniamo un risultato simile a quello mostrato in basso.
[ prova_git ] $ git init
Initialized empty Git repository in /Users/claudio/guida_git/prova_git/.git/
Git conferma che un nuovo repository vuoto è stato inizializzato contestualmente alla creazione di una nuova cartella .git. Inizieremo ad analizzare il contenuto di questa cartella nella prossima lezione. Possiamo ora visualizzare nuovamente il contenuto della directory prova_git con il comando sottostante che mostra tutti i file e le cartelle presenti, ad eccezione di ‘.’ e ‘..’ (opzione -A), disposti su una sola colonna (opzione -1).
[ prova_git ] (master) $ ls -1A
.git
africa
antartide
asia
europa
mete_turistiche_dicembre.txt
nord_america
oceania
sud_america
Le tre aree principali di lavoro in Git
A questo punto è necessario parlare di quelle che sono le tre aree principali con cui si ha a che fare quando si utilizza Git per un progetto, ovvero Working Tree, Staging Area (denominata anche Index) e Local Repository (Trascuriamo per il momento l’esistenza di un eventuale repository remoto).
- il Working Tree o Working Directory corrisponde alla directory di lavoro in cui sono presenti i vari file di un progetto. In ogni istante sarà presente una specifica versione di ogni file. Come vedremo nei prossimi articoli, è possibile recuperare dal Repository una certa versione di uno o più file che avevamo precedentemente salvato al suo interno.
- la Staging Area o Index può essere vista come un’area di transizione. Si tratta di un file contenuto all’interno della directory .git che contiene le informazioni relative ai prossimi file che saranno inseriti nel Repository. La comodità di avere la Staging Area è rappresentata dal fatto che possiamo modificare più file all’interno della Working Directory e selezionare quali file dovranno essere inseriti nel prossimo snapshot che verrà salvato nel Repository. (A breve vedremo un esempio)
- il Local Repository è la struttura dati in cui salveremo le diverse istantanee dei file che avevamo precedentemente inserito all’interno della Staging Area. Come abbiamo già detto, Git mantiene al suo interno tutti gli snapshot salvati della Working Directory. Grazie ai dati salvati nel repository è possibile ‘navigare indietro nel tempo’ e visualizzare o ripristinare i dati contenuti in uno o più file o la struttura di intere cartelle.
La procedura base da seguire nell’utilizzare Git, può essere quindi sintetizzata nei seguenti tre passi:
- si lavora su uno o più file nella Working Directory;
- vengono scelti i file da aggiungere alla Staging Area (questi file saranno quelli che verranno inseriti nel prossimo snapshot – Commit – che sarà salvato nel Repository);
- attraverso il comando git commit si prelevano gli ultimi file presenti nella Staging Area e vengono salvati nella prossima istantanea (commit) che sarà conservata nel Repository.
Ritornando al nostro esempio, possiamo vedere lo stato corrente del Working Tree, attraverso il comando git status.
[ prova_git ] (master) $ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
mete_turistiche_dicembre.txt
nothing added to commit but untracked files present (use "git add" to track)
Come potete notare dall’output del comando, Git ci informa che è presente un Untracked file. Git si è accorto che è stato aggiunto un file nella directory, ma tale file non è stato ancora aggiunto nella Staging Area e quindi non è ancora presente all’interno del Repository. Notate che non sono elencate le sottocartelle che avevamo creato. Il motivo è che tali cartelle sono attualmente vuote. Vedremo a breve un semplice trucco per far in modo che Git ‘riconosca’ anche le cartelle vuote. Git suggerisce anche il comando (git add <file>…) da digitare per aggiungere dei file alla Staging Area.
[ prova_git ] (master) $ git add mete_turistiche_dicembre.txt
A questo punto abbiamo aggiunto il file mete_turistiche_dicembre.txt nella Staging Area. Se digitiamo nuovamente il comando git status, possiamo vedere il nuovo stato del Working Tree.
[ prova_git ] (master) $ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: mete_turistiche_dicembre.txt
Git evidenzia il fatto che un nuovo file è pronto per essere inserito nel Repository attraverso il comando git commit.
Eseguiamo quindi il comando git commit con l’opzione -m <message> che permette di specificare il messaggio che verrà inserito nello snapshot (commit) salvato nel repository. Nel corso di questa guida non presteremo troppa attenzione allo stile e alla struttura dei messaggi dei vari commit. Quando però si lavora in team con Git è opportuno seguire delle linee guida e inserire nei messaggi dei commit informazioni dettagliate e esplicative che possano essere utili a tutti i membri del team per comprendere esattamente quali file sono stati cambiati e che tipo di modifiche sono state apportate a un progetto. (Nell’immagine mostrata in alto abbiamo soltanto mostrato il file e non l’intera struttura dati del repository al fine di semplificare e rendere più leggibile l’immagine.)
[ prova_git ] (master) $ git commit -m 'First commit'
[master (root-commit) 360d369] First commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 mete_turistiche_dicembre.txt
Possiamo quindi lanciare il comando git status e Git confermerà che non ci sono ulteriori modifiche al nostro progetto di cui non è già a conoscenza.
[ prova_git ] (master) $ git status
On branch master
nothing to commit, working tree clean
Ora possiamo provare ad aggiungere due nuovi file all’interno delle cartelle nord_america e europa.
[ prova_git ] (master) $ touch nord_america/moraine_lake.txt
[ prova_git ] (master) $ touch europa/kakslauttanen_arctic_resort.txt
Inseriamo dunque le due nuove destinazioni nel file mete_turistiche_dicembre.txt
# Mete turistiche dicembre
1. nord_america/moraine_lake
2. europa/kakslauttanen_arctic_resort
Lanciamo ora il comando git status per visualizzare nuovamente lo stato aggiornato del Working Tree.
[ prova_git ] (master) $ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: mete_turistiche_dicembre.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
europa/
nord_america/
no changes added to commit (use "git add" and/or "git commit -a")
Come potevamo immaginare, un file è stato aggiornato e sono presenti due nuovi Untracked File (nuovi file di cui Git non tiene ancora tracci) che possiamo aggiungere alla Staging Area. Procediamo con l’aggiungere il file europa/kakslauttanen_arctic_resort.txt e visualizziamo successivamente il nuovo stato del Working Tree.
[ prova_git ] (master) $ git add europa
[ prova_git ] (master) $ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: europa/kakslauttanen_arctic_resort.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: mete_turistiche_dicembre.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
nord_america/
Il file europa/kakslauttanen_arctic_resort.txt è quindi pronto per essere aggiunto al Repository.
[ prova_git ] (master) $ git commit -m 'Aggiunge la destinazione europa/kakslauttanen_arctic_resort.txt'
[master aded011] Aggiunge la destinazione europa/kakslauttanen_arctic_resort.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 europa/kakslauttanen_arctic_resort.txt
Visualizziamo nuovamente lo stato della Working Directory.
[ prova_git ] (master) $ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: mete_turistiche_dicembre.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
nord_america/
no changes added to commit (use "git add" and/or "git commit -a")
Ripetiamo gli stessi passaggi per il file nord_america/moraine_lake.txt.
[ prova_git ] (master) $ git add nord_america
[ prova_git ] (master) $ git commit -m 'Aggiunge la destinazione nord_america/moraine_lake.txt'
[master 0c0715f] Aggiunge la destinazione nord_america/moraine_lake.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 nord_america/moraine_lake.txt
[ prova_git ] (master) $ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: mete_turistiche_dicembre.txt
no changes added to commit (use "git add" and/or "git commit -a")
Infine creiamo un nuovo commit nel Repository per il file mete_turistiche_dicembre.txt modificato.
[ prova_git ] (master) $ git commit -am 'Aggiunge moraine_lake e kakslauttanen_arctic_resort nel file mete_turistiche_dicembre.txt'
[master 2fdffd3] Aggiunge moraine_lake e kakslauttanen_arctic_resort nel file mete_turistiche_dicembre.txt
1 file changed, 3 insertions(+)
[ prova_git ] (master) $ git status
On branch master
nothing to commit, working tree clean
In quest’ultimo caso, invece di lanciare il comando git add seguito da git commit -m <messaggio>, abbiamo eseguito il comando equivalente git commit -am <messaggio>. Ciò è possibile perché il file mete_turistiche_dicembre.txt era stato modificato ed era già stato aggiunto in precedenza alla Staging Area. L’opzione -a non funziona con i file Untracked.
A questo punto possiamo usare il comando git log per mostrare tutti i commit finora presenti all’interno del repository.
[ prova_git ] (master) $ git log
commit 2fdffd3dbc3700287560aaabea93c9737898916f
Author: Claudio M <claudio@example.it>
Date: Fri Dec 8 20:31:53 2017 +0000
Aggiunge moraine_lake e kakslauttanen_arctic_resort nel file mete_turistiche_dicembre.txt
commit 0c0715fa7dd796a40c3a91bf6ca8b4d55545b2bf
Author: Claudio M <claudio@example.it>
Date: Fri Dec 8 20:28:44 2017 +0000
Aggiunge la destinazione nord_america/moraine_lake.txt
commit aded0117fc132b6694b999d523e8f05660079f86
Author: Claudio M <claudio@example.it>
Date: Fri Dec 8 20:21:22 2017 +0000
Aggiunge la destinazione europa/kakslauttanen_arctic_resort.txt
commit 360d369eecf2dcca411fdf003af3af72811ca35b
Author: Claudio M <claudio@example.it>
Date: Fri Dec 8 17:47:25 2017 +0000
First commit
Tutti i commit presenti nel repository vengono mostrati in ordine cronologico inverso, dal più recente fino al primo commit aggiunto. Vengono anche mostrate le informazioni sull’autore del commit e la data. È inoltre presente una stringa di 40 caratteri corrispondente al digest generato da Git per ogni commit usando l’algoritmo di hash SHA-1. Si tratta di una stringa che identifica in maniera univoca il commit (approfondiremo l’argomento nella prossima lezione)
Tenere traccia delle cartelle vuote
Per concludere vediamo come fare per tener traccia di una directory vuota che, come abbiamo visto, non è possibile aggiungere nel repository se non presenta almeno un file al suo interno. Il metodo più semplice e più usato è quello di aggiungere al suo interno un file con il nome .gitkeep. Aggiungiamo allora un file del genere all’interno della directory antartide ed eseguiamo il comando git status.
[ prova_git ] (master) $ touch antartide/.gitkeep
[ prova_git ] (master) $ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
antartide/
nothing added to commit but untracked files present (use "git add" to track)
A questo punto potremmo aggiungere la directory antartide alla Staging Area e poi nel Repository come abbiamo già visto in precedenza. In questo caso però decidiamo di rimuovere il file appena aggiunto che è ancora nello stato Untracked.
[ prova_git ] (master) $ rm antartide/.gitkeep
[ prova_git ] (master) $ git status
On branch master
nothing to commit, working tree clean
Conclusioni
In questa lezione abbiamo introdotto alcuni semplici comandi per inizializzare un repository e iniziare a usare Git per tenere traccia dei file del nostro progetto. Abbiamo visto che esistono fondamentalmente tre aree di lavoro in cui risiedono i file. Nella prossima lezione approfondiremo il funzionamento di Git, cominceremo ad analizzare il contenuto della cartella .git, cercheremo di capire meglio cosa contiene un repository e come fa Git a tener traccia dei diversi file e cartelle di un progetto.