Introduction
Git nomme chaque objet par le hachage cryptographique de son contenu. C'est le stockage adressé par contenu : le nom est l'empreinte du contenu. Le hachage par défaut est SHA-1 (160 bits, 40 caractères hex). Le support de SHA-256 existe expérimentalement depuis Git 2.29.
Comment un hachage est calculé
Git préfixe le contenu brut d'un en-tête de la forme <type> <size>\0, puis hache :
printf 'blob 6\0hello\n' | sha1sum
# ce013625030ba8dba906f756967f9e9ca394464a -
La même valeur sort de git hash-object :
printf 'hello\n' | git hash-object --stdin
# ce013625030ba8dba906f756967f9e9ca394464a
Pourquoi l'adressage par contenu
- Déduplication : contenu identique stocké une seule fois.
- Intégrité : toute corruption change le hachage, instantanément détectable.
- Reproductibilité : le même tree a toujours le même nom.
- Synchro distribuée : Git peut demander « avez-vous
abc123? » sans expliquer ce que c'est.
Hachages abrégés
Git accepte le préfixe non ambigu le plus court, normalement 7 caractères. À mesure qu'un dépôt grandit, plus de chiffres peuvent être nécessaires :
git rev-parse --short HEAD
git rev-parse --short=12 HEAD
git config --global core.abbrev 12
SHA-1 vs SHA-256
SHA-1 a des attaques de collision connues (SHAttered, 2017). Le projet Git a répondu avec SHA-256 comme format d'objet alternatif. Pour créer un dépôt SHA-256 :
git init --object-format=sha256
Note : les dépôts SHA-1 et SHA-256 ne peuvent pas encore interagir ; le support des outils et de l'hébergement mûrit encore à partir de Git 2.45+. Pour l'instant, la plupart des projets continuent avec SHA-1, augmenté par l'implémentation SHA-1 durcie de Git détectant les collisions.
Vérifier l'intégrité
git fsck --full
git fsck --strict
git fsck recalcule les hachages pour chaque objet et signale toute non-correspondance.
Inspecter un objet
git cat-file -t <sha> # type
git cat-file -s <sha> # taille
git cat-file -p <sha> # contenu joliment imprimé
SHA-1 durci
Depuis 2017, Git est livré avec une implémentation SHA-1 « détectant les collisions » (sha1dc) qui reconnaît le motif SHAttered publié et refuse de hacher de telles entrées. Cela rend les attaques pratiques contre les dépôts Git essentiellement impossibles sans découvrir une nouvelle technique de collision. Le coût est un léger ralentissement du hachage ; vous pouvez opter pour le SHA-1 OpenSSL standard avec ./configure --with-openssl-sha1 lors de la compilation depuis les sources, mais peu d'utilisateurs ont une raison de le faire.
git --version --build-options 2>&1 | grep -i sha
Erreurs fréquentes
S'inquiéter que les collisions SHA-1 compromettent votre dépôt. Les attaques connues nécessitent des entrées élaborées ; Git détecte de plus le motif de collision publié. Le risque pragmatique pour un projet normal est essentiellement nul. Tronquer les hachages trop agressivement dans les scripts ; dans un dépôt avec un million d'objets, 7 caractères peuvent entrer en collision. Utilisez git rev-parse --short pour laisser Git choisir. Éditer les fichiers d'objets directement sous .git/objects ; cela casse l'invariant d'adressage par contenu et corrompt le dépôt. Toutes les écritures doivent passer par la plomberie Git.