Einführung
Git speichert Objekte in zwei physischen Formaten. Lose Objekte sind einzelne Dateien; gepackte Objekte leben in einer Pack-Datei mit einem Delta-komprimierten Body. Beide Formen beschreiben dieselben logischen Objekte, adressiert durch dieselben Hashes.
Loses Layout
Jedes lose Objekt liegt unter .git/objects/xx/yyy..., wobei xx die ersten zwei Hex-Zeichen des SHA sind und yyy... die verbleibenden 38. Die Datei besteht aus den zlib-deflatierten Bytes von <type> <size>\0<content>:
find .git/objects -type f -name '??' -prune -o -type f -print | head
git cat-file -p <sha>
Pack-Layout
.git/objects/pack/pack-<hash>.pack
.git/objects/pack/pack-<hash>.idx
Die .idx-Datei bildet SHA auf Byte-Offset im .pack ab; ohne sie würde das Pack einen linearen Scan erfordern.
Wie Objekte zwischen Formen wechseln
Neue Objekte werden lose geschrieben. Sie werden gepackt, wenn:
git gcläuft (manuell oder automatisch).git repackaufgerufen wird.- Ein Fetch oder Push sie als Pack überträgt.
git fast-importsie direkt in ein Pack schreibt.
git gc
git repack -a -d
git count-objects -v
count-objects -v meldet die Anzahl loser, die gesamte Festplattennutzung und Pack-Statistiken.
Abwägungen
- Lose: einfach, leicht zu inspizieren, schnell beim Schreiben eines einzelnen Objekts. Langsam bei Millionen.
- Gepackt: kompakt, Delta-komprimiert, schnell zum Massen-Lesen. Erfordert Repacking zur Aufnahme neuer Objekte.
Auto-gc
Git löst ein Auto-gc aus, wenn zu viele lose Objekte angesammelt sind. Einstellbare Werte:
git config gc.auto 6700 # Schwellenwert für lose Objekte
git config gc.autoPackLimit 50 # Schwellenwert für Anzahl der Packs
git config gc.auto 0 # Auto-gc deaktivieren (nicht empfohlen)
Ein Pack inspizieren
git verify-pack -v .git/objects/pack/pack-<hash>.idx | head
git verify-pack -s .git/objects/pack/pack-<hash>.idx
Sie sehen Objekttypen, gepackte Größen, Deltas und Kettentiefen.
Wiederherstellung nach Korruption
git fsck --full
cp -r broken-repo backup
git unpack-objects < .git/objects/pack/pack-<hash>.pack
unpack-objects löst ein Pack zurück in lose Form, nützlich, wenn ein einzelnes schlechtes Objekt in einem Pack viele Operationen lahmlegt.
Ein Objekt nachschlagen
Wenn Git einen SHA auflöst, sucht es in dieser Reihenfolge: lose Objektdatei, dann jede Pack-idx, dann Alternates (objects/info/alternates). Die Suche ist dank der Fanout-Tabelle der idx im Wesentlichen pro Pack konstant in der Zeit. Der Performance-Einfluss vieler kleiner Packs gegenüber einem großen Pack ist real, weshalb gc konsolidiert:
git count-objects -v
cat .git/objects/info/alternates 2>/dev/null
git verify-pack -s .git/objects/pack/pack-<hash>.idx
Alternates erlauben es mehreren Repositories, einen Pool von Objekten auf der Festplatte zu teilen; git clone --shared erstellt ein solches Setup und spart Platz auf Kosten gewisser Sicherheit.
Häufige Fehler
Manuelles Löschen von pack--Dateien zur Speicherrückgewinnung; das zerstört erreichbare Historie. Verwenden Sie git gc. Auto-gc auf langlebigen Repositories deaktivieren und mit Millionen loser Objekte enden, was jede Operation verlangsamt. git gc --aggressive regelmäßig laufen lassen, wenn ein normales gc ausreichen würde; aggressives Packen ist teuer. Schließlich: Ein Repository mit cp -r kopieren, während ein Pack geschrieben wird, und mit einem korrupten Index enden. Verwenden Sie git clone --local für sichere Kopien.