Skip to content

03. Concetti fondamentali

Il repository Git è la directory nascosta .git dentro la cartella del progetto: lì sono salvati tutti i dati necessari a gestire cronologia e stato.

my-project/
├── .git/ <- il vero repository (index, refs/, oggetti, ...)
├── README.md
└── server.php

Punti chiave:

  • eliminando .git si elimina l’intera cronologia: la cartella torna una normale directory;
  • non tutti i file della cartella fanno parte del repository — solo quelli esplicitamente aggiunti.

Si ottiene un repository in due modi: inizializzandolo (git init) o clonandone uno esistente (git clone).

Un commit è uno snapshot (istantanea) del repository in un determinato momento. Particolari importanti:

  • non salva solo le differenze tra due versioni, ma l’istantanea (compressa) di tutti i file inclusi nel repository al momento del commit;
  • se un file non cambia tra due commit, non viene duplicato: viene memorizzato un riferimento alla versione precedente;
  • ogni commit conosce il suo commit genitore (parent).

Il commit è l’entità base su cui si fondano i repository Git.

La working copy (o working directory / working tree) è ciò che Git mette a disposizione dello sviluppatore sul proprio computer quando estrae dalla history uno specifico commit. Quando si clona un repository, Git: crea una directory locale vuota, copia tutti gli snapshot del remote in .git, individua l’ultimo commit ed estrae i file corrispondenti.

I file nella working copy possono trovarsi in tre stati rispetto allo snapshot di origine:

StatoSignificato
Unmodifiedil file ha lo stesso contenuto dello snapshot
Untrackedil file non è presente nello snapshot
Modifiedil file contiene modifiche rispetto allo snapshot

La staging area è il luogo “virtuale” in cui si raccolgono le modifiche della working copy destinate al prossimo commit. Serve perché spesso non tutte le modifiche sono “buone” da salvare: un buon sviluppatore committa solo modifiche funzionanti o rilevanti.

Si possono mettere in staging sia interi file sia singole porzioni di modifiche. Se modifichi un file, lo metti in staging, lo rimodifichi e poi committi, nel commit finirà solo la prima modifica.

Alle tre condizioni del paragrafo precedente va quindi aggiunto lo stato Staged, riferibile alle singole modifiche.

Un branch in Git non è un contenitore di commit, ma un puntatore a un commit con un superpotere: quando si effettua un nuovo commit, il puntatore si sposta automaticamente sul commit più recente. Il commit puntato è chiamato tip o head del branch.

Alla creazione di un repository con git init, Git crea un branch di default (tipicamente main o master). Più branch possono puntare allo stesso commit: ad esempio, per lavorare alla versione 2.0 di un progetto mantenendo contemporaneamente i fix della 1.x, basta creare un nuovo branch che parta dal commit della versione 1.0 — da lì in poi le due history divergono.

È utile distinguere ciò che si fa “in pratica” (estrarre un branch nella working copy, vedere la cronologia di un branch) da ciò che Git fa internamente (estrarre lo snapshot che è la HEAD del branch, ricostruire i commit genitori, confrontare snapshot).

Git non prescrive come usare i branch: nel tempo sono emerse alcune strategie comuni (vedi sezione 14).

Un remote è un repository remoto a cui il repository locale è collegato. Quando si clona un repository, Git salva il riferimento (URL) alla sorgente: per convenzione il remote iniziale si chiama origin.

I branch locali possono essere collegati ai corrispondenti branch remoti: così è possibile sapere se ci sono differenze (in più o in meno) rispetto alla controparte remota. Possono esistere più remote, scegliendo di volta in volta da quale recuperare o a quale inviare dati.