Da Anonimo (non verificato) , 29 Aprile 2026

Introduzione

Un clone shallow scarica solo i più recenti N commit di un branch invece della storia completa. Il risultato è molto più piccolo e veloce da scaricare, al costo di una storia incompleta.

Creare

git clone --depth 1 https://github.com/example/widget.git
git clone --depth 50 https://github.com/example/widget.git
git clone --depth 1 --branch v1.2.3 --single-branch <url>

La directory .git contiene un file shallow che elenca i commit i cui parent sono stati omessi.

Perché shallow

  • Build CI: hanno bisogno solo dei sorgenti per HEAD.
  • Container e Dockerfile: immagini più piccole.
  • Tooling one-shot che non ha bisogno della storia.

Limitazioni

  • Non puoi pushare da un clone shallow se il tuo push dipende da commit che il server non ha (raro, ma possibile).
  • git log si ferma al confine shallow.
  • Alcune operazioni (rebase attraverso il confine, blame su righe vecchie) non possono funzionare.
  • Fino a Git 2.11 il cloning shallow su HTTP non era supportato; Git moderno lo gestisce.

Approfondire e unshallow

git fetch --depth 100              # estendi la profondità
git fetch --deepen 50              # aggiungi 50 commit in più
git fetch --shallow-since=2024-01-01
git fetch --unshallow              # scarica la storia completa

Dopo --unshallow il repo si comporta come un clone normale.

Single-branch e shallow

--single-branch + --depth 1 è il clone più piccolo possibile utile. Per tracciare altri branch dopo:

git remote set-branches --add origin main feature
git fetch origin

Partial clone (un'ottimizzazione diversa)

Se hai bisogno della storia completa ma non di tutti i blob, usa invece un partial clone:

git clone --filter=blob:none <url>
git clone --filter=tree:0 <url>

I partial clone scaricano la storia ma rimandano i blob (o tree) finché non sono necessari. Sono di solito una scelta migliore di shallow quando il server li supporta.

Rilevare lo stato shallow

git rev-parse --is-shallow-repository
cat .git/shallow

Pattern CI

Molti provider CI hanno default shallow clone (depth 1 o 50). Se la tua build esegue git describe o ha bisogno di blame tra versioni, richiedi un clone completo:

# GitHub Actions
- uses: actions/checkout@v4
  with:
    fetch-depth: 0

File shallow e graft

Il file shallow in .git/ elenca SHA di commit i cui parent sono intenzionalmente mancanti. Git li tratta come root durante la traversata del grafo. Il meccanismo correlato ma deprecato info/grafts ti permetteva di falsificare relazioni parent; usa invece git replace --graft, che è più sicuro e si replica via fetch:

cat .git/shallow
git replace --graft <commit> <new-parent>
git replace -l
git replace -d <commit>

Questo è occasionalmente utile per cucire insieme storie importate senza riscrivere i commit.

Errori comuni

Eseguire git describe in un clone depth-1 e ottenere un errore perché nessun tag annotated è raggiungibile; o scarica i tag (--tags) o usa un clone più profondo. Provare a fare rebase di un feature branch in un clone shallow dove la merge base è oltre il confine shallow; approfondisci prima. Pushare da un clone shallow ed essere sorpresi da "remote rejected"; il server può aver bisogno di oggetti parent mancanti. Infine, trattare i clone shallow come sostituto dei partial clone; risolvono problemi diversi e i partial sono di solito più amichevoli.