Von Gast (nicht überprüft) , 29 April 2026

Einführung

Gits inhaltsadressiertes Modell dedupliziert identische Objekte, aber ähnliche-aber-nicht-identische Blobs (eine Datei und ihre spätere Bearbeitung) würden weiterhin volle Größe kosten. Pack-Dateien lösen das mit Delta-Kompression: Speichern eines Objekts als Basis plus eine Sequenz von "copy/insert"-Anweisungen, die ein anderes Objekt erzeugen.

Wie es funktioniert

Beim Packen vergleicht Git Kandidatenobjekte (üblicherweise Blobs ähnlicher Größe und Typs) und wählt eine Basis für jedes. Das Delta zeichnet auf:

  • Das Basisobjekt (per Offset im Pack oder per SHA).
  • Größen von Basis und Ziel.
  • Einen Strom von copy- (Bytes aus der Basis verwenden) und insert-Anweisungen (literale Bytes).

Der Delta-Strom wird dann zlib-komprimiert.

Deltas inspizieren

git verify-pack -v .git/objects/pack/pack-<hash>.idx | head -20

Die Ausgabe enthält Spalten für gepackte Größe, Tiefe und Basis-SHA für Delta-Einträge. Ein Nicht-Delta-Objekt hat keine Basis.

Einstellbare Werte

git config pack.window 250          # pro Objekt geprüfte Kandidaten
git config pack.depth 50            # maximale Kettenlänge
git config pack.threads 4
git config pack.windowMemory 100m
git config pack.deltaCacheSize 256m

pack.window steuert, wie aggressiv Git nach guten Basen sucht; pack.depth begrenzt, wie lang Delta-Ketten wachsen können.

Aggressives vs. normales Repack

git repack -a -d                    # Standard
git repack -a -d --depth=250 --window=250   # aggressiv
git gc --aggressive

Aggressive Repacks werfen vorhandene Deltas weg und berechnen sie von Grund auf neu, kosten CPU, verbessern aber möglicherweise das Ergebnis.

Erreichbarkeit und Bitmaps

Server kombinieren Delta-Packing oft mit Erreichbarkeits-Bitmaps für schnelle Clone-Set-Berechnung:

git repack -adb

Warum manche Objekte nicht deltifiziert werden

  • Kryptografisch zufällige Daten (bereits inkomprimierbar).
  • Objekte, deren einzige Kandidaten kleiner sind als der konfigurierte Schwellenwert.
  • Objekte außerhalb der Reichweite des Pack-Fensters.

Pack-übergreifende Deltas

Multi-Pack-Indexe (git multi-pack-index) plus der Repack-Modus --geometric (Git 2.33+) machen es möglich, Deltas effizient über viele Packs hinweg zu pflegen:

git repack --geometric=2 -d

Dies ist das empfohlene Schema für große Repositories.

Delta-Inseln

Für Server-Betreiber, die viele Forks desselben Projekts hosten, partitionieren Delta-Inseln Objekte so, dass Deltas nur innerhalb der Ref-Menge eines Forks geschehen, was schnelles Klonen jedes einzelnen Forks ermöglicht:

git config pack.island "refs/remotes/(.*)/heads"
git config pack.islandCore "main"
git repack -adb

Ohne Inseln könnte ein Objekt, das nur aus Fork A erreichbar ist, gegen ein Objekt deltifiziert werden, das nur aus Fork B erreichbar ist; Forks A's Klon zu bedienen würde dann erfordern, auch Objekte aus B zu senden. Die meisten Nutzer brauchen das nie, aber es ist die Geheimzutat hinter der Pack-Server-Performance von GitHub, GitLab und Bitbucket.

Häufige Fehler

Annehmen, Deltas seien vorwärts (neuer = Basis) oder rückwärts (älter = Basis); Git ist agnostisch und wählt das, was ein kleineres Delta ergibt. Packs zwischen Repositories mit verschiedenen SHA-Präfixen kopieren; die Daten sind inhaltsadressiert, also funktioniert das, aber das Umbenennen von Dateien basierend auf Teil-Hashes kann brechen. Absurd hohe pack.depth-Werte verfolgen, um kleine Packs zu erreichen; tiefere Ketten bedeuten langsameren Objektzugriff (jedes Delta in der Kette muss angewendet werden). Schließlich: Erwarten, dass Delta-Kompression Speicher bei bereits komprimierten Binärdateien (Videos, JPGs) spart; tut sie fast nie. Verwenden Sie dafür Git LFS.