Da Anonimo (non verificato) , 29 Aprile 2026

Introduzione

Tutto ciò che Git sa su un repository vive in .git/. Sapere cosa è ogni entry rimuove il mistero dalle diagnostiche "cosa è appena successo?".

Layout di alto livello

.git/
  HEAD                # ref simbolico al branch corrente
  config              # configurazione locale del repository
  description         # usato da gitweb
  index               # la staging area
  packed-refs         # ref di branch e tag impacchettati (opzionale)
  hooks/              # script di hook lato client
  info/               # file di exclude e altre info locali al repo
  logs/               # reflog
  objects/            # tutti gli oggetti (loose + pack/)
  refs/               # branch, tag, tracking remoto
  worktrees/          # worktree linkati (se ci sono)
  modules/            # directory .git dei submodule

HEAD e refs

cat .git/HEAD
ls .git/refs/heads
ls .git/refs/remotes/origin
ls .git/refs/tags
cat .git/packed-refs | head

objects/

Oggetti loose sotto objects/xx/, oggetti packed in objects/pack/. Non toccare a mano.

logs/

Il reflog. logs/HEAD registra ogni movimento di HEAD; logs/refs/heads/<branch> registra la storia di ogni branch.

cat .git/logs/HEAD | head

hooks/

Script di hook di esempio, tutti chiamati *.sample per default. Per abilitare, togli il suffisso e rendi eseguibile:

cd .git/hooks
cp pre-commit.sample pre-commit
chmod +x pre-commit

info/

info/exclude è un file di ignore per repo, per clone (non committato). info/refs è generato da git update-server-info per server HTTP dumb.

config

Configurazione locale in formato INI. Modifica via git config --local o git config -e:

cat .git/config
git config --local user.email "[email protected]"

worktrees/

Ogni worktree linkato ha una directory sotto .git/worktrees/<name>/ con il proprio HEAD, index e logs.

modules/

Per i repo con submodule, la directory .git di ogni submodule vive qui, e la working tree del submodule contiene un piccolo file .git che punta ad essa.

Repository bare

Un repo bare ha gli stessi contenuti ma al livello superiore (nessun wrapper .git/) e nessuna working tree. Convenzione: nominare la directory project.git.

git rev-parse per i path

Gli script che hanno bisogno di trovare path dentro .git/ non dovrebbero mai assumere che la directory sia letteralmente chiamata .git. I submodule usano un file .git che punta altrove; i worktree hanno gitdir linkati; i repo bare non hanno gitdir separato. Usa git rev-parse:

git rev-parse --git-dir              # gitdir effettiva per il repo corrente
git rev-parse --git-common-dir       # dir condivisa per i worktree
git rev-parse --show-toplevel        # radice della working tree
git rev-parse --is-inside-git-dir
git rev-parse --is-inside-work-tree

Queste cinque domande coprono quasi ogni controllo "dove sono?" di cui uno script ha bisogno.

Errori comuni

Modificare i file dentro .git/ direttamente. Quasi tutto ha un comando Git che lo fa correttamente, atomicamente e con gli hook. Fare backup solo della working tree e dimenticare che .git/ contiene l'intera storia; fai il backup di tutta la directory. Condividere .git/hooks/ assumendo che si propaghi; gli hook non sono versionati. Usa core.hooksPath o uno strumento come pre-commit per condividerli. Infine, cancellare .git/index d'impulso; ricostruisci con git read-tree HEAD, ma solo dopo aver fatto un backup.