Interne Struktur von git-Repositories
Übersicht
- Git ist ein versioniertes Dateisystem basierend auf dem Dateisystem des Betriebssystems.
- Git verwaltet lediglich Snapshots des Working Trees in sehr effizienter Art und Weise (stupid content tracker).
Refs
-
refs sind Referenzen auf Commit-Objekte. Diese zeigen auf den aktuellen head-Commit von (Remote) Branches und werden auch verwendet, um Tags zu verwalten:
$ git show-ref 7dd09b0f0bbaf4be50cc6a6d4cc663d6e69b949a refs/heads/master 947ff2fedd38ef457cacd4f75648ce9d4ea21839 refs/heads/newfeature ba2c18111460e99e478fbb2a27d103ab08e04d81 refs/remotes/origin/master
-
Beispiel: Branch “newfeature” entspricht “refs/heads/newfeature”, “origin/master” entspricht “refs/remotes/origin/master”.
-
Die Ablage erfolgt unter .git/refs/heads/* bzw. .git/packed-refs.
-
.git/HEAD verweist auf den aktiven Branch/Commit:
$ cat .git/HEAD ref: refs/heads/master
Commits
-
refs zeigen auf commit-Objekte. Ein commit-Objekt zeigt auf ein oder mehrere parent-commit-Objekte sowie auf ein tree-Objekt:
$ git show -s --pretty=raw master commit 7dd09b0f0bbaf4be50cc6a6d4cc663d6e69b949a tree bc6a0455812a35001e97ef1ee68f98642550fd4e parent c75d103a515c16190217c2bca93726dc30f05e67 author Ralf Ebert <info@ralfebert.de> 1274813398 +0200 committer Ralf Ebert <info@ralfebert.de> 1274813398 +0200 test
Tree
-
Ein tree-Objekt ist vergleichbar mit einem Ordner, es enthält Objekte vom Typ blob (Dateien) und tree (Unterordner):
$ git show -s --pretty=raw bc6a0455812a35001e97ef1ee68f98642550fd4e tree bc6a0455812a35001e97ef1ee68f98642550fd4e .gitignore readme.txt src/ docs/ $ git ls-tree bc6a0455812a35001e97ef1ee68f98642550fd4e 100644 blob 9ba36b0138fdcd501064a77e271d249e383799db .gitignore 100644 blob b1be62814cf5c55ebb7fa3af0f3c3db033230be1 readme.txt 040000 tree 619c76e40cf251d551a3284b8f0d41100d0b10e6 src/ 040000 tree 30b9351ff0fbc8cba63949aa3c2af1c9cb3ab7ec docs/
Tags
- Tags existieren in zwei Varianten, standardmäßig werden “leichtgewichtige” Tags in refs/tags/* angelegt, um den zugehörigen Commit zu referenzieren.
- Tag 1.0 entspricht refs/tags/1.0.
- Solche leichtgewichtigen Tags müssen mit git push --tags explizit übertragen werden.
- Ein “schwergewichtiges” Git-Objekt vom Typ tag wird angelegt, wenn der Tag mit GnuPG signiert wird (git tag -s).
Arbeiten mit Objekten
-
Einige Namen sind mehrdeutig, master referenziert sowohl refs/heads/master als auch den dazugehörigen Tree, dies kann konkretisiert werden mit:
master^{commit} master^{tree}
-
Typ eines Git-Objektes anzeigen:
$ git cat-file -t 72d3736bca59513f5b7352a550a553602adabbe6 commit
-
Inhalte anzeigen:
$ git show -s --pretty=raw [object] $ git cat-file [blob|tree|commit|tag] [object]
.git Verzeichnisstruktur
.git
|-- HEAD # Referenz auf aktiven Commit
|-- config # Repository-Konfiguration
|-- description # Repository-Beschreibung
|-- hooks/ # Automatisch auszuführende Aktionen
|-- index # Index (git ls-files --stage)
|-- logs/ # Lokales Revision-Log, siehe reflog, für commit@{...}
|-- objects/ # Ablage der commit, tree, blob, tag-Objekte
`-- refs/ # Branch/Tag-Referenzen -> Commit Hash, auch in packed-refs
Repositorypflege
-
Git hat eine sehr platzsparende Objektstruktur (bspw.: Datei unverändert - vorhandenes Blob wird referenziert)
-
Historie wird aus Performancegründen nicht automatisch komprimiert.
-
Objekte, die nicht mehr referenziert werden (z.B. nach git reset), werden nicht automatisch aufgeräumt.
-
Aufräumen und Komprimieren der Objekte sollte hin und wieder durchgeführt werden (spart Platz, bringt Performance) mit:
git gc
Aufgaben
- Lassen Sie mit git show-ref alle Referenzen in Ihrem Repository anzeigen.
- Lassen Sie mit git show -s --pretty=raw [object] das letzte Commit-Objekt sowie den zugehörigen Tree ausgeben.
- Legen Sie einen Tag an und pushen Sie diesen in das Remote-Repository.
- Führen Sie git gc aus, um das Repository zu komprimieren.