Einführung
Ein Shallow Clone lädt nur die jüngsten N Commits eines Branches herunter statt die vollständige Historie. Das Ergebnis ist deutlich kleiner und schneller zu fetchen, auf Kosten einer unvollständigen Historie.
Erstellen
git clone --depth 1 https://github.com/example/widget.git
git clone --depth 50 https://github.com/example/widget.git
git clone --depth 1 --branch v1.2.3 --single-branch <url>
Das .git-Verzeichnis enthält eine shallow-Datei, die Commits auflistet, deren Eltern weggelassen wurden.
Warum shallow
- CI-Builds: brauchen nur den Source für HEAD.
- Container und Dockerfiles: kleinere Images.
- Einmal-Tooling, das keine Historie braucht.
Einschränkungen
- Sie können von einem Shallow Clone nicht pushen, wenn Ihr Push von Commits abhängt, die der Server nicht hat (selten, aber möglich).
git loghält an der Shallow-Grenze an.- Manche Operationen (Rebase über die Grenze, Blame auf alten Zeilen) können nicht funktionieren.
- Bis Git 2.11 war Shallow-Cloning über HTTP nicht unterstützt; modernes Git handhabt es.
Vertiefen und Unshallow
git fetch --depth 100 # Tiefe erweitern
git fetch --deepen 50 # 50 weitere Commits hinzufügen
git fetch --shallow-since=2024-01-01
git fetch --unshallow # vollständige Historie herunterladen
Nach --unshallow verhält sich das Repository wie ein normaler Klon.
Single-Branch und Shallow
--single-branch + --depth 1 ist der kleinstmögliche nützliche Klon. Um später andere Branches zu tracken:
git remote set-branches --add origin main feature
git fetch origin
Partial Clones (eine andere Optimierung)
Wenn Sie die volle Historie, aber nicht alle Blobs brauchen, verwenden Sie stattdessen einen Partial Clone:
git clone --filter=blob:none <url>
git clone --filter=tree:0 <url>
Partial Clones laden Historie, verschieben aber Blobs (oder Trees) bis zum Bedarf. Sie sind üblicherweise eine bessere Wahl als Shallow, wenn der Server sie unterstützt.
Shallow-Zustand erkennen
git rev-parse --is-shallow-repository
cat .git/shallow
CI-Muster
Viele CI-Anbieter verwenden standardmäßig Shallow Clones (Tiefe 1 oder 50). Wenn Ihr Build git describe ausführt oder Blame über Versionen hinweg braucht, fordern Sie einen vollständigen Klon an:
# GitHub Actions
- uses: actions/checkout@v4
with:
fetch-depth: 0
Shallow-Dateien und Grafts
Die shallow-Datei in .git/ listet Commit-SHAs auf, deren Eltern absichtlich fehlen. Git behandelt sie als Wurzeln bei der Graph-Traversierung. Der verwandte, aber deprecated info/grafts-Mechanismus erlaubte es, Eltern-Beziehungen zu fälschen; verwenden Sie stattdessen git replace --graft, was sicherer ist und sich über Fetch repliziert:
cat .git/shallow
git replace --graft <commit> <new-parent>
git replace -l
git replace -d <commit>
Das ist gelegentlich nützlich, um importierte Historien zusammenzufügen, ohne Commits umzuschreiben.
Häufige Fehler
git describe in einem depth-1-Klon laufen lassen und einen Fehler erhalten, weil kein Annotated Tag erreichbar ist; entweder Tags fetchen (--tags) oder einen tieferen Klon verwenden. Versuchen, einen Feature-Branch in einem Shallow Clone zu rebasen, wo die Merge-Basis jenseits der Shallow-Grenze liegt; vertiefen Sie zuerst. Aus einem Shallow Clone pushen und durch "remote rejected" überrascht sein; der Server kann fehlende Eltern-Objekte brauchen. Schließlich: Shallow Clones als Ersatz für Partial Clones behandeln; sie lösen verschiedene Probleme, und Partial ist üblicherweise freundlicher.