Da Anonimo (non verificato) , 29 Aprile 2026

Introduzione

git fetch è l'operazione di rete che scarica nuovi oggetti e aggiorna i ref di tracking remoto. Non cambia i tuoi branch o la working tree, il che lo rende il comando "cosa c'è di nuovo?" più sicuro.

La sequenza

  1. Risolve l'URL del remote.
  2. Apre una connessione (HTTPS, SSH o git://).
  3. Negozia capabilities (versione del protocollo, multi-ack, filtri partial clone, ecc.).
  4. Il server pubblicizza i ref (o, nel protocollo v2, solo quelli che corrispondono ai pattern richiesti).
  5. Il client riporta cosa ha già.
  6. Il server invia un pack file contenente gli oggetti mancanti.
  7. Il client scrive il pack in .git/objects/pack/ e lo indicizza.
  8. Il client aggiorna i ref di tracking remoto (refs/remotes/origin/*).
  9. Opzionalmente fa prune dei ref cancellati.

Comandi

git fetch
git fetch origin
git fetch --all
git fetch --prune
git fetch origin main:my-main         # fetch in un ref locale

La sintassi colon main:my-main crea o aggiorna un ref locale direttamente; usala con cura.

Ispezionare cosa è stato scaricato

git fetch origin
cat .git/FETCH_HEAD
git log HEAD..origin/main --oneline

FETCH_HEAD elenca ogni ref aggiornato dal fetch più recente, nell'ordine richiesto.

Refspec

Ogni remote ha uno o più refspec di fetch. Il default per origin:

+refs/heads/*:refs/remotes/origin/*

Puoi aggiungerne altri, ad esempio per scaricare i ref pull-request da GitHub:

git config --add remote.origin.fetch '+refs/pull/*/head:refs/remotes/origin/pr/*'
git fetch
git switch -c review/123 origin/pr/123

Pruning

Senza prune, i branch cancellati sul server restano come ref origin/* obsoleti:

git fetch --prune
git config --global fetch.prune true

Tag

Per default, fetch scarica i tag che puntano ai commit scaricati. Forza o disabilita:

git fetch --tags
git fetch --no-tags

Trace e debug

GIT_TRACE=1 GIT_TRACE_PACKET=1 git fetch
GIT_CURL_VERBOSE=1 git fetch        # HTTPS

Questi rivelano richieste esatte, utili per debuggare proxy o auth.

Negoziazione e haves

L'handshake di fetch è una danza di "wants" e "haves". Il client elenca cosa vuole (gli SHA di punta dei branch remoti), e offre haves (commit locali recenti) così il server può calcolare un pack minimale. Git moderno usa l'algoritmo di negoziazione skipping, che converge in O(log n) round anche su lunghe storie. Puoi regolarlo:

git config fetch.negotiationAlgorithm skipping
git config fetch.negotiationAlgorithm consecutive
GIT_TRACE_PACKET=1 git fetch 2>&1 | grep -E 'have|want' | head

Errori comuni

Credere che git fetch cambi i tuoi branch; non lo fa mai. Usa git pull o git merge origin/main per integrare. Saltare --prune in clone di lunga vita e accumulare dozzine di ref origin/* obsoleti. Configurare male un refspec a mano e sovrascrivere branch locali; doppio controllo con git config -e. Infine, fare fetch da un partial clone senza rendersi conto che alcuni oggetti richiederanno una chiamata di rete successiva quando vi si accede; i partial clone scambiano velocità iniziale per latenza occasionale dopo.