Die vier fundamentalen Objekttypen in Git đď¸
Git ist im Kern eine inhaltsadressierte Datenbank â jedes Objekt wird durch seinen SHA-1-Hash identifiziert. Diese Architektur basiert auf genau vier fundamentalen Objekttypen, die zusammen die gesamte Versionshistorie abbilden.
Die Objekttypen im Ăberblick
Blob â der Dateiinhalt đ
Ein Blob (Binary Large Object) speichert den reinen Inhalt einer Datei â ohne Metadaten wie Dateinamen oder Berechtigungen. Zwei Dateien mit identischem Inhalt teilen sich denselben Blob, unabhängig von ihrem Namen oder Speicherort.
Eigenschaften:
- Enthält ausschlieĂlich den Dateiinhalt (Text oder Binärdaten)
- Kennt seinen eigenen Dateinamen nicht
- Wird durch den SHA-1-Hash seines Inhalts identifiziert
Tree â die Verzeichnisstruktur đł
Ein Tree repräsentiert ein Verzeichnis und verknĂźpft Dateinamen mit Blobs oder weiteren Trees (fĂźr Unterverzeichnisse). Er fungiert als âInhaltsverzeichnis" eines Ordners zu einem bestimmten Zeitpunkt.
Jeder Eintrag in einem Tree enthält:
- Den Dateimodus (z.B.
100644fĂźr normale Dateien,040000fĂźr Verzeichnisse) - Den Objekttyp (
blobodertree) - Den SHA-1-Hash des referenzierten Objekts
- Den Datei- oder Verzeichnisnamen
Commit â der Schnappschuss mit Geschichte đ¸
Ein Commit ist der zentrale Objekttyp fĂźr die Versionskontrolle. Er referenziert einen Tree (den Zustand des gesamten Projekts) und enthält Metadaten zur Ănderung.
Bestandteile eines Commits:
- Referenz auf den Root-Tree (Projektzustand)
- Referenz(en) auf Parent-Commit(s) â bei Merge-Commits mehrere
- Autor (wer die Ănderung ursprĂźnglich erstellt hat)
- Committer (wer den Commit ins Repository eingefĂźgt hat)
- Zeitstempel fĂźr beide
- Die Commit-Nachricht
Tag â der benannte Meilenstein đˇď¸
Ein annotiertes Tag ist ein eigenständiges Objekt, das auf einen Commit zeigt und zusätzliche Informationen enthält. Es dient typischerweise zur Markierung von Releases.
Bestandteile:
- Referenz auf das getaggte Objekt (meist ein Commit)
- Tag-Name
- Tagger (Name und E-Mail)
- Zeitstempel
- Tag-Nachricht
đĄ Hinweis: Sogenannte lightweight Tags sind keine eigenen Objekte, sondern nur Referenzen (wie Branches). Nur annotierte Tags (
git tag -a) erzeugen ein Tag-Objekt.
Wie die Objekte zusammenhängen
Die Objekte bilden einen gerichteten azyklischen Graphen (DAG), in dem jedes Objekt auf andere verweist:
flowchart TB
subgraph Commits
C1["Commit abc123\nInitial commit"]
C2["Commit def456\nAdd feature"]
end
subgraph Trees
T1["Tree 1\nRoot-Verzeichnis"]
T2["Tree 2\nRoot-Verzeichnis"]
T3["Tree 3\nUnterordner src"]
end
subgraph Blobs
B1["Blob\nREADME.md"]
B2["Blob\nindex.js"]
B3["Blob\napp.js"]
end
subgraph Tags
TAG["Tag v1.0.0"]
end
TAG --> C2
C2 --> C1
C2 --> T2
C1 --> T1
T1 --> B1
T2 --> B1
T2 --> T3
T3 --> B2
T3 --> B3
style TAG fill:#e1bee7,color:#000000
style C1 fill:#bbdefb,color:#000000
style C2 fill:#bbdefb,color:#000000
style T1 fill:#c8e6c9,color:#000000
style T2 fill:#c8e6c9,color:#000000
style T3 fill:#c8e6c9,color:#000000
style B1 fill:#fff9c4,color:#000000
style B2 fill:#fff9c4,color:#000000
style B3 fill:#fff9c4,color:#000000
Wichtige Zusammenhänge:
- Ein Commit zeigt immer auf genau einen Tree (den Root-Tree)
- Ein Tree zeigt auf Blobs (Dateien) und/oder andere Trees (Unterverzeichnisse)
- Ein Commit zeigt auf seine Parent-Commits (auĂer der allererste)
- Ein Tag zeigt typischerweise auf einen Commit
Objekte inspizieren mit git cat-file đ
Das Kommando git cat-file ist dein Werkzeug, um âunter die Haube" zu schauen. Es hat mehrere nĂźtzliche Optionen:
| Option | Beschreibung |
|---|---|
-t |
Zeigt den Typ des Objekts |
-s |
Zeigt die GrĂśĂe in Bytes |
-p |
Zeigt den Inhalt pretty-printed |
Praktische Beispiele
-
Typ eines Objekts ermitteln:
git cat-file -t HEADAusgabe:
commit -
Einen Commit inspizieren:
git cat-file -p HEADAusgabe:
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 parent 8a7b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b author Max Mustermann <max@example.de> 1719670258 +0200 committer Max Mustermann <max@example.de> 1719670258 +0200 Implement user authentication -
Den Tree eines Commits anschauen:
Zunächst den Tree-Hash aus dem Commit extrahieren, dann:
git cat-file -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904Ausgabe:
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad README.md 100644 blob a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 package.json 040000 tree 9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e src -
Einen Blob (Dateiinhalt) lesen:
git cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dadAusgabe:
# Mein Projekt Dies ist die README-Datei des Projekts. -
Ein annotiertes Tag inspizieren:
git cat-file -p v1.0.0Ausgabe:
object 8a7b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b type commit tag v1.0.0 tagger Max Mustermann <max@example.de> 1719670258 +0200 Release version 1.0.0 - Production ready
NĂźtzliche AbkĂźrzungen
Du musst nicht immer den vollständigen SHA-1-Hash angeben:
# Die ersten 7 Zeichen reichen meist
git cat-file -p abc1234
# HEAD und andere Referenzen funktionieren
git cat-file -p HEAD
git cat-file -p main
git cat-file -p v1.0.0
# Der Tree des aktuellen Commits
git cat-file -p HEAD^{tree}
# Eine bestimmte Datei im aktuellen Commit
git cat-file -p HEAD:src/index.js
Wo liegen diese Objekte? đ
Alle Objekte werden im Verzeichnis .git/objects/ gespeichert. Die ersten zwei Zeichen des Hashes bilden einen Unterordner, der Rest ist der Dateiname:
.git/objects/
âââ 3b/
â âââ 18e512dba79e4c8300dd08aeb37f8e728b8dad â Blob
âââ 4b/
â âââ 825dc642cb6eb9a060e54bf8d69288fbee4904 â Tree
âââ 8a/
â âââ 7b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b â Commit
âââ pack/
âââ ... â Komprimierte Objekte (nach git gc)
Die Dateien sind mit zlib komprimiert â deshalb kannst du sie nicht direkt lesen, sondern brauchst git cat-file.
đŻ Tipp: Mit
git count-objects -vsiehst du, wie viele Objekte dein Repository enthält und wie viel Speicherplatz sie belegen.