Da Anonimo (non verificato) , 29 Aprile 2026

Introduzione

Git nomina ogni oggetto con l'hash crittografico del suo contenuto. Questo è storage indirizzato per contenuto: il nome è l'impronta digitale del contenuto. L'hash predefinito è SHA-1 (160 bit, 40 caratteri esadecimali). Il supporto per SHA-256 esiste sperimentalmente da Git 2.29.

Come viene calcolato un hash

Git antepone un header della forma <type> <size>\0 al contenuto grezzo, poi lo hasha:

printf 'blob 6\0hello\n' | sha1sum
# ce013625030ba8dba906f756967f9e9ca394464a  -

Lo stesso valore esce da git hash-object:

printf 'hello\n' | git hash-object --stdin
# ce013625030ba8dba906f756967f9e9ca394464a

Perché l'indirizzamento per contenuto

  • Deduplicazione: contenuti identici memorizzati una sola volta.
  • Integrità: qualsiasi corruzione cambia l'hash, immediatamente rilevabile.
  • Riproducibilità: lo stesso tree ha sempre lo stesso nome.
  • Sync distribuito: Git può chiedere "hai abc123?" senza spiegare cosa sia.

Hash abbreviati

Git accetta il prefisso più corto non ambiguo, normalmente 7 caratteri. Man mano che un repo cresce, possono servire più cifre:

git rev-parse --short HEAD
git rev-parse --short=12 HEAD
git config --global core.abbrev 12

SHA-1 contro SHA-256

SHA-1 ha attacchi di collisione noti (SHAttered, 2017). Il progetto Git ha risposto con SHA-256 come formato oggetto alternativo. Per creare un repo SHA-256:

git init --object-format=sha256

Nota: i repo SHA-1 e SHA-256 non possono ancora interoperare; il supporto di tooling e hosting sta ancora maturando da Git 2.45+. Per ora, la maggior parte dei progetti continua con SHA-1, integrato dall'implementazione SHA-1 di Git con rilevamento di collisioni.

Verificare l'integrità

git fsck --full
git fsck --strict

git fsck ricalcola gli hash per ogni oggetto e segnala qualsiasi mismatch.

Ispezionare un oggetto

git cat-file -t <sha>       # tipo
git cat-file -s <sha>       # dimensione
git cat-file -p <sha>       # contenuto pretty-printed

SHA-1 con hardening

Dal 2017 Git è distribuito con un'implementazione SHA-1 "con rilevamento collisioni" (sha1dc) che riconosce il pattern SHAttered pubblicato e rifiuta di hashare tali input. Questo rende gli attacchi pratici contro i repository Git essenzialmente impossibili senza scoprire una nuova tecnica di collisione. Il costo è un piccolo rallentamento sull'hashing; puoi optare per OpenSSL SHA-1 standard con ./configure --with-openssl-sha1 quando compili dai sorgenti, ma pochi utenti hanno motivo di farlo.

git --version --build-options 2>&1 | grep -i sha

Errori comuni

Preoccuparsi che le collisioni SHA-1 compromettano il tuo repo. Gli attacchi noti richiedono input forgiati; Git inoltre rileva il pattern di collisione pubblicato. Il rischio pragmatico per un progetto normale è essenzialmente zero. Troncare gli hash troppo aggressivamente negli script; in un repo con un milione di oggetti, 7 caratteri possono collidere. Usa git rev-parse --short per lasciare scegliere a Git. Modificare i file oggetto direttamente sotto .git/objects; questo rompe l'invariante di indirizzamento per contenuto e corrompe il repo. Tutte le scritture devono passare attraverso il plumbing di Git.