Lezione 3 di 35

Git 03

🔀 Git & GitHub · Modulo 1 · Lezione 03

Il primo repository 📦

git init · git add · git commit · La cartella .git · Il tuo primo snapshot

⏱️ Durata stimata: 60–75 min 📊 Livello: Base (Modulo 1) 🔧 Strumenti: Terminale (Git Bash / Terminal) · Editor di testo 📋 Prerequisiti: Lezioni 01–02 (Git installato e configurato)

🎉 Questa è la lezione in cui metti le mani sulla tastiera per la prima volta. Creerai un repository Git da zero, aggiungerai dei file, farai il tuo primo commit e guarderai dentro la cartella .git per capire cosa fa Git dietro le quinte. Alla fine di questa lezione, avrai un repository funzionante con una storia di commit — il tuo primo progetto versionato.

🎯 Obiettivi della lezione

  • Creare un repository Git con git init
  • Capire cosa contiene la cartella .git e perché è importante
  • Aggiungere file alla staging area con git add
  • Creare un commit (snapshot) con git commit
  • Scrivere messaggi di commit chiari e utili
  • Fare più commit e costruire una storia
  • Usare git status per capire in ogni momento lo stato del repository

📖 1. Teoria

1.1 — git init: creare un repository

Un repository (repo) è una cartella il cui contenuto è tracciato da Git. Per trasformare una normale cartella in un repository Git, basta un comando:

git init
Questo comando crea una sotto-cartella nascosta chiamata .git all’interno della cartella corrente. Da quel momento, Git osserva tutto ciò che succede nella cartella e può tracciare le modifiche.

Cosa succede esattamente quando esegui git init?

$ mkdir mio-progetto
$ cd mio-progetto
$ ls -la
total 0
drwxr-xr-x 2 studente studente 40 mar 10 09:00 .
drwxr-xr-x 15 studente studente 480 mar 10 09:00 ..

$ git init
Initialized empty Git repository in /home/studente/mio-progetto/.git/

$ ls -la
total 0
drwxr-xr-x 3 studente studente 60 mar 10 09:00 .
drwxr-xr-x 15 studente studente 480 mar 10 09:00 ..
drwxr-xr-x 7 studente studente 200 mar 10 09:00 .git
La cartella .git è apparsa. Il punto davanti al nome la rende “nascosta” — per questo serve ls -la (con il flag -a) per vederla.

⚠️ Non cancellare mai la cartella .git! Contiene tutta la storia del tuo progetto — ogni commit, ogni branch, tutto. Se la cancelli, perdi l’intero storico e la cartella torna a essere una normale cartella senza versioning. I file rimangono, ma la storia scompare per sempre.

1.2 — Cosa c’è dentro .git

Non devi modificare nulla dentro .git — Git lo gestisce da solo. Ma guardare dentro aiuta a capire che Git non è magia: è un sistema elegante fatto di file e cartelle.

$ ls .git/
HEAD
config
description
hooks/
info/
objects/
refs/
File / Cartella Cosa contiene
HEAD Un puntatore al branch corrente (es. ref: refs/heads/main). Dice a Git “dove ti trovi adesso”.
config Le impostazioni locali di questo repository (quelle impostate senza --global).
objects/ Il “database” di Git: tutti i file, le directory e i commit, memorizzati come oggetti compressi identificati da hash SHA.
refs/ I puntatori ai commit: branch (refs/heads/) e tag (refs/tags/). Un branch è letteralmente un file di testo con dentro un hash.
hooks/ Script automatici che Git può eseguire in certi momenti (prima di un commit, dopo un push…). Per ora puoi ignorarli.

📌 Il concetto chiave: tutto ciò che Git sa del tuo progetto vive dentro .git. I file che vedi nella cartella del progetto sono solo la “versione attiva” — la working directory. La storia completa (tutti gli snapshot di tutti i commit) è compressa e memorizzata in .git/objects/. Ecco perché Git è così veloce: non deve contattare nessun server per ricostruire qualsiasi versione passata.

1.3 — git status: la bussola del repository

git status è il comando che userai più di qualsiasi altro. Ti dice esattamente cosa sta succedendo nel repository: quali file sono stati modificati, quali sono pronti per il commit, quali Git non sta tracciando. È la tua bussola — usala prima e dopo ogni operazione.

# In un repository appena creato, senza file:
$ git status
On branch main

No commits yet

nothing to commit (create/copy files and use “git add” to track)
Git ti dice: sei sul branch main, non hai ancora fatto commit e non c’è nulla da committare. Ti suggerisce anche cosa fare dopo — Git è sorprendentemente bravo a darti consigli.

Vediamo cosa succede quando creiamo un file:

$ echo “# Il mio progetto” > README.md
$ git status
On branch main

No commits yet

Untracked files:
(use “git add <file>…” to include in what will be committed)
README.md

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

Il file README.md è in rosso sotto “Untracked files”: Git lo vede, ma non lo sta ancora tracciando. È nella working directory ma non nella staging area. Git ti suggerisce di usare git add per includerlo.

1.4 — git add: preparare il commit

git add sposta i file dalla working directory alla staging area — l’area di preparazione dove selezioni cosa andrà nel prossimo commit. Ricordi l’analogia del carrello dalla Lezione 01? git add è il gesto di mettere un prodotto nel carrello.

Comando Cosa fa Quando usarlo
git add nomefile Aggiunge un singolo file alla staging area Quando vuoi committare solo un file specifico
git add file1 file2 Aggiunge più file alla staging area Quando vuoi committare un gruppo di file correlati
git add . Aggiunge tutti i file modificati e nuovi Quando vuoi committare tutto. Usalo con attenzione.
$ git add README.md
$ git status
On branch main

No commits yet

Changes to be committed:
(use “git rm –cached <file>…” to unstage)
new file: README.md
Ora README.md è in verde sotto “Changes to be committed”. È nella staging area — pronto per essere salvato con il prossimo commit.
Il viaggio del file — da “sconosciuto” a “pronto per il commit”
Untracked
Git lo vede ma
non lo traccia
→
git add
Staged
Nella staging area
pronto per il commit
→
git commit
Committed
Salvato nella storia
per sempre

⚠️ Errore comune — git add . senza pensare: aggiungere tutto con il punto è comodo ma pericoloso. Potresti includere file temporanei, password, file di configurazione locale o cartelle pesanti come node_modules/. Per ora, con pochi file, va bene. Nella Lezione 15 imparerai a creare un .gitignore per escludere automaticamente i file indesiderati.

1.5 — git commit: salvare lo snapshot

git commit prende tutto ciò che è nella staging area e lo salva come uno snapshot permanente nel repository. Ogni commit ha:

🔑
Hash SHA univoco
Un codice tipo a3b8f2c che identifica questo commit in modo unico nell’universo. Non esistono due commit con lo stesso hash.
👤
Autore + data
Il nome e l’email che hai configurato con git config, più il timestamp preciso al secondo.
💬
Messaggio
Una descrizione scritta da te che spiega cosa hai cambiato e perché. È l’informazione più preziosa del commit.
$ git commit -m “Primo commit: aggiunto README con titolo del progetto”
[main (root-commit) a3b8f2c] Primo commit: aggiunto README con titolo del progetto
1 file changed, 1 insertion(+)
create mode 100644 README.md
Fatto! Il tuo primo commit. Git ti dice: è sul branch main, è il root-commit (il primo in assoluto), il suo hash abbreviato è a3b8f2c, ha coinvolto 1 file con 1 riga aggiunta.

Il flag -m ti permette di scrivere il messaggio direttamente nel comando. Se ometti -m, Git apre l’editor che hai configurato nella Lezione 02 — scrivi il messaggio, salvi e chiudi, e il commit viene creato.

1.6 — Scrivere buoni messaggi di commit

Il messaggio di commit è la cosa che leggerai più spesso quando guarderai la storia del progetto. Un buon messaggio risponde alla domanda: “Se qualcuno legge questo messaggio tra 6 mesi, capirà cosa è successo?”

❌ Messaggi inutili
“fix”
“update”
“cose”
“asdfghj”
“commit”
“modifiche varie”
“WIP”
Tra una settimana non saprai più cosa hai fatto. Tra un mese, nemmeno ricorderai di aver fatto questo commit.
✅ Messaggi utili
“Aggiunto README con descrizione del progetto”
“Corretta formula del calcolo IVA”
“Aggiunta pagina contatti con form”
“Rimosso file di test dimenticato”
“Risolto bug: il totale non si aggiornava”
“Aggiornate dipendenze a versione 2.1”
Chiari, specifici, utili. Leggendo la storia si capisce cosa è successo al progetto.
Le 3 regole d’oro del messaggio di commit
1. Inizia con un verbo “Aggiunto…”, “Corretta…”, “Rimosso…”, “Aggiornato…”. Il messaggio completa la frase: “Questo commit ha…”
2. Sii specifico Non “fix bug” ma “Corretto calcolo sconto: applicava il 10% invece del 15%”. Più è preciso, più è utile in futuro.
3. Massimo ~50 caratteri La prima riga del messaggio è il “titolo” — breve e diretto. Se serve spiegare di più, aggiungi una riga vuota e poi un paragrafo di dettaglio.

1.7 — Il ciclo completo: modifica → add → commit

Ora hai tutti i pezzi. Il workflow quotidiano con Git è un ciclo che ripeterai migliaia di volte nella tua carriera:

1. Modifica
Crea o modifica file
→
2. Status
git status
→
3. Add
git add file
→
4. Commit
git commit -m "..."
Ripeti. Ogni ciclo aggiunge uno snapshot alla storia del progetto.

Il passo 2 (git status) sembra superfluo, ma è fondamentale: ti assicura di sapere esattamente cosa stai per committare. Con il tempo diventerà automatico — come guardare lo specchietto prima di svoltare.

1.8 — Cosa succede dopo il commit?

$ git status
On branch main
nothing to commit, working tree clean
“Working tree clean” — tutto è stato salvato. La working directory e il repository sono sincronizzati. È lo stato “perfetto” — da qui puoi iniziare a fare nuove modifiche.
# Vediamo la storia (un solo commit per ora)
$ git log
commit a3b8f2c9e1d7a45b8c2f6e3d1a9b7c5e4f8d2a1 (HEAD -> main)
Author: Mario Rossi <mario.rossi@email.it>
Date: Tue Mar 10 09:15:32 2026 +0100

Primo commit: aggiunto README con titolo del progetto
Ecco il tuo primo commit nella storia. L’hash completo è lungo 40 caratteri — normalmente si usa la versione abbreviata (7 caratteri). HEAD -> main ti dice che sei sul branch main e che questo è il commit più recente.

💻 2. Esempi guidati

Esempio A — Creare un repository e fare 3 commit

Esegui ogni comando nel terminale, uno alla volta. Dopo ogni passo, leggi l’output e confrontalo con quello atteso.

# === PREPARAZIONE ===
$ cd ~/Desktop # o dove preferisci
$ mkdir diario-git
$ cd diario-git
$ git init
Initialized empty Git repository in …/diario-git/.git/

# === COMMIT 1: README ===
$ echo “# Diario Git” > README.md
$ echo “Il mio primo progetto con Git.” >> README.md
$ git status # README.md in rosso (untracked)
$ git add README.md
$ git status # README.md in verde (staged)
$ git commit -m “Aggiunto README con titolo e descrizione”

# === COMMIT 2: nuovo file ===
$ echo “Oggi ho creato il mio primo repository Git!” > giorno1.txt
$ git status # giorno1.txt in rosso
$ git add giorno1.txt
$ git commit -m “Aggiunto giorno1: primo giorno con Git”

# === COMMIT 3: modifica file esistente + nuovo file ===
$ echo “## Diario” >> README.md # aggiunge una riga al README
$ echo “Oggi ho imparato git add e git commit.” > giorno2.txt
$ git status # README.md in rosso (modified), giorno2.txt in rosso (untracked)
$ git add . # aggiunge tutto
$ git status # entrambi in verde
$ git commit -m “Aggiunto giorno2 e aggiornato README con sezione Diario”

Esempio B — Guardare la storia

$ git log –oneline
e5f2a1b Aggiunto giorno2 e aggiornato README con sezione Diario
c8d3f4a Aggiunto giorno1: primo giorno con Git
a3b8f2c Aggiunto README con titolo e descrizione
Tre commit, ordinati dal più recente al più vecchio. I tuoi hash saranno diversi — sono unici per ogni repository. Con l’alias della Lezione 02 puoi anche scrivere git lg.

Esempio C — Esplorare .git dopo i commit

# Cosa dice HEAD?
$ cat .git/HEAD
ref: refs/heads/main

# Cosa contiene il branch main?
$ cat .git/refs/heads/main
e5f2a1b9c3d7a45b8c2f6e3d1a9b7c5e4f8d2a1b

# Quanti oggetti ha creato Git?
$ find .git/objects -type f | wc -l
9
HEAD punta al branch main. Il branch main contiene l’hash dell’ultimo commit. Git ha creato 9 oggetti: 3 commit + 3 “tree” (che descrivono la struttura delle cartelle) + 3 “blob” (il contenuto dei file). Non devi ricordare questi dettagli — ma ora sai che Git non è magia: è un database di oggetti.

🏋️ 3. Esercizi

🟢 Esercizio 1 — Il tuo primo repo (Facile)

Crea un repository chiamato ricette. All’interno:

a) Crea un file README.md con il testo “# Le mie ricette preferite”. Fai il primo commit.
b) Crea un file pasta.txt con una ricetta a tua scelta. Fai il secondo commit.
c) Crea un file dolce.txt con una ricetta di un dolce. Fai il terzo commit.
d) Esegui git log --oneline e verifica che ci siano 3 commit con messaggi chiari.
e) Esegui git status e verifica che dica “working tree clean”.

🔵 Esercizio 2 — Staging selettiva (Medio)

Questo esercizio dimostra che puoi scegliere cosa committare:

a) Nel repository ricette, crea due nuovi file: pizza.txt e insalata.txt.
b) Esegui git status — entrambi sono untracked.
c) Aggiungi solo pizza.txt alla staging area: git add pizza.txt.
d) Esegui git status — pizza.txt è in verde, insalata.txt è ancora in rosso.
e) Fai il commit: git commit -m "Aggiunta ricetta della pizza".
f) Esegui git status — solo insalata.txt rimane untracked.
g) Ora aggiungi e committa anche insalata.txt con un suo commit separato.
h) Esegui git log --oneline — devi avere 5 commit totali.

Domanda: perché è utile fare due commit separati invece di uno solo con entrambi i file?

🟠 Esercizio 3 — Modifica + nuovo file nello stesso commit (Medio)

a) Modifica il file README.md: aggiungi una riga “Raccolta iniziata a marzo 2026”.
b) Crea un nuovo file contorno.txt con una ricetta.
c) Esegui git status. Osserva: il README è “modified” (rosso) e il contorno è “untracked” (rosso). Sono in due categorie diverse.
d) Aggiungi entrambi con git add . ed esegui git status — entrambi sono in verde.
e) Fai un singolo commit con un messaggio che descriva entrambe le modifiche.
f) Verifica con git log --oneline.

🟣 Esercizio 4 — Indagine su .git (Difficile)

Questo esercizio ti fa esplorare la struttura interna di Git. Non devi capire tutto — l’obiettivo è demistificare la “magia”.

a) Apri il file .git/HEAD e leggi il contenuto. A quale branch punta?
b) Apri il file in .git/refs/heads/main. Cosa contiene? Confronta l’hash con l’output di git log --oneline — corrisponde all’ultimo commit?
c) Conta gli oggetti nel database Git: find .git/objects -type f | wc -l. Quanti sono? Riesci a spiegare approssimativamente perché quel numero? (Suggerimento: ogni commit genera ~2-3 oggetti.)
d) Apri .git/config — ci sono le impostazioni locali? Se hai seguito solo la Lezione 02, probabilmente non ce ne sono (perché hai usato solo --global).
e) Esperimento distruttivo (fallo su un repo di test, non su uno importante): rinomina la cartella .git in .git-backup. Esegui git status. Cosa succede? Poi rinomina di nuovo in .git e ripeti git status.

❓ 4. Quiz di verifica

1. Cosa fa il comando git init?

Mostra risposta

Crea una sotto-cartella nascosta .git all’interno della cartella corrente, trasformandola in un repository Git. Da quel momento Git può tracciare le modifiche ai file nella cartella. Non modifica né cancella nessun file esistente — aggiunge solo la cartella .git. Il repository è vuoto (nessun commit) e pronto per il primo git add + git commit.


2. Qual è la differenza tra git add e git commit?

Mostra risposta

git add sposta i file dalla working directory alla staging area — li seleziona per il prossimo commit, ma non li salva ancora. git commit prende tutto ciò che è nella staging area e lo salva come uno snapshot permanente nel repository, con autore, data e messaggio. Sono due passi separati perché ti permettono di controllare esattamente cosa finisce in ogni commit — puoi avere 10 file modificati e committarne solo 3, lasciando gli altri per un commit successivo.


3. Hai creato un file ma non hai fatto git add. Viene salvato nel commit?

Mostra risposta

No. Un file che non è stato aggiunto alla staging area con git add non viene incluso nel commit. Git lo segnalerà come “untracked” (se è nuovo) o “modified” (se esisteva già ed è stato cambiato) nell’output di git status. Solo i file in verde sotto “Changes to be committed” vengono inclusi nel prossimo commit. Per questo è importante fare git status prima di ogni commit — per verificare che tutto ciò che vuoi salvare sia nella staging area.


4. Cosa succede se cancelli la cartella .git?

Mostra risposta

Perdi tutta la storia del progetto: tutti i commit, tutti i branch, tutta la configurazione locale. I file nella cartella del progetto rimangono (sono nella working directory, non dentro .git), ma la cartella torna a essere una normale directory senza versioning. Eseguire git status darà errore: “fatal: not a git repository”. La storia è irrecuperabile a meno che tu non abbia un’altra copia del repository (ad esempio su GitHub o sul computer di un collaboratore) — ed è proprio questo il vantaggio di un VCS distribuito.


5. Qual è un buon messaggio di commit per questa modifica: “aggiunta la formula per calcolare lo sconto del 15% nella funzione calcolaPrezzo()”?

Mostra risposta

Un buon messaggio sarebbe: "Aggiunta formula sconto 15% in calcolaPrezzo()". Inizia con un verbo (“Aggiunta”), è specifico (dice cosa è stato aggiunto e dove), e sta sotto i 50 caratteri. Messaggi come “fix”, “update”, “modifiche” sarebbero pessimi perché non dicono nulla su cosa è cambiato. Se serve più contesto, puoi aggiungere una riga vuota e poi un paragrafo di dettaglio — ma il titolo deve essere breve e chiaro.


6. Qual è la differenza tra un file “untracked” e un file “modified” in git status?

Mostra risposta

Untracked significa che il file è nuovo — Git non l’ha mai visto prima. Non è stato incluso in nessun commit precedente. Modified significa che il file era già tracciato da Git (è stato committato almeno una volta), ma è stato modificato dopo l’ultimo commit. In entrambi i casi il file appare in rosso in git status, ma in sezioni diverse: “Untracked files” per i nuovi, “Changes not staged for commit” per i modificati. Entrambi richiedono git add per essere inclusi nel prossimo commit.


📚 Riepilogo della lezione

Cosa hai imparato oggi:
  • git init — crea un repository (aggiunge la cartella .git)
  • git status — la tua bussola: mostra file untracked, modified, staged
  • git add nomefile — sposta i file nella staging area (seleziona per il commit)
  • git add . — aggiunge tutto (con cautela)
  • git commit -m "messaggio" — salva lo snapshot nel repository
  • git log --oneline — mostra la storia compatta
  • La cartella .git contiene tutta la storia — non cancellarla mai
  • Messaggi di commit: verbo + dettaglio specifico + max ~50 caratteri
  • Il ciclo: modifica → git status → git add → git commit → ripeti

Prossima lezione →

Lezione 04 — Il ciclo di lavoro
Working directory → staging area → repository in profondità.
I tre stati di un file. git status letto come un professionista.

Corso Git & GitHub · Per studenti e insegnanti · Lezione 03 di 45