Einführung
Git benennt jedes Objekt nach dem kryptografischen Hash seines Inhalts. Das ist inhaltsadressierte Speicherung: Der Name ist der Fingerabdruck des Inhalts. Der Standard-Hash ist SHA-1 (160 Bit, 40 Hex-Zeichen). SHA-256-Unterstützung existiert seit Git 2.29 experimentell.
Wie ein Hash berechnet wird
Git stellt dem Rohinhalt einen Header der Form <type> <size>\0 voran und hasht dann:
printf 'blob 6\0hello\n' | sha1sum
# ce013625030ba8dba906f756967f9e9ca394464a -
Derselbe Wert kommt aus git hash-object:
printf 'hello\n' | git hash-object --stdin
# ce013625030ba8dba906f756967f9e9ca394464a
Warum Inhaltsadressierung
- Deduplizierung: identischer Inhalt einmal gespeichert.
- Integrität: jede Korruption ändert den Hash, sofort erkennbar.
- Reproduzierbarkeit: derselbe Tree hat immer denselben Namen.
- Verteilte Synchronisation: Git kann fragen "habt ihr
abc123?" ohne zu erklären, was es ist.
Abgekürzte Hashes
Git akzeptiert das kürzeste eindeutige Präfix, üblicherweise 7 Zeichen. Mit wachsendem Repository können mehr Stellen nötig sein:
git rev-parse --short HEAD
git rev-parse --short=12 HEAD
git config --global core.abbrev 12
SHA-1 versus SHA-256
SHA-1 hat bekannte Kollisionsangriffe (SHAttered, 2017). Das Git-Projekt antwortete mit SHA-256 als alternativem Objektformat. Um ein SHA-256-Repository zu erstellen:
git init --object-format=sha256
Hinweis: SHA-1- und SHA-256-Repositories können noch nicht zusammenarbeiten; Tooling- und Hosting-Unterstützung reift noch ab Git 2.45+. Vorerst bleiben die meisten Projekte bei SHA-1, ergänzt durch Gits gehärtete kollisionserkennende SHA-1-Implementierung.
Integrität verifizieren
git fsck --full
git fsck --strict
git fsck berechnet Hashes für jedes Objekt neu und meldet jede Abweichung.
Ein Objekt inspizieren
git cat-file -t <sha> # Typ
git cat-file -s <sha> # Größe
git cat-file -p <sha> # schön formatierter Inhalt
Gehärtetes SHA-1
Seit 2017 wird Git mit einer "kollisionserkennenden" SHA-1-Implementierung (sha1dc) ausgeliefert, die das veröffentlichte SHAttered-Muster erkennt und sich weigert, solche Eingaben zu hashen. Dies macht praktische Angriffe gegen Git-Repositories im Wesentlichen unmöglich, ohne eine neue Kollisionstechnik zu entdecken. Der Preis ist eine kleine Verlangsamung beim Hashen; Sie können sich beim Bauen aus dem Quellcode mit ./configure --with-openssl-sha1 für das Standard-OpenSSL-SHA-1 entscheiden, doch nur wenige Nutzer haben Grund dazu.
git --version --build-options 2>&1 | grep -i sha
Häufige Fehler
Sich Sorgen machen, dass SHA-1-Kollisionen Ihr Repository kompromittieren. Die bekannten Angriffe erfordern speziell konstruierte Eingaben; Git erkennt zusätzlich das veröffentlichte Kollisionsmuster. Das pragmatische Risiko für ein normales Projekt ist im Wesentlichen null. Hashes in Skripten zu aggressiv abkürzen; in einem Repository mit einer Million Objekten können 7 Zeichen kollidieren. Verwenden Sie git rev-parse --short und lassen Sie Git wählen. Objektdateien direkt unter .git/objects bearbeiten; das bricht die Inhaltsadress-Invariante und korrumpiert das Repository. Alle Schreibvorgänge müssen über Git-Plumbing erfolgen.