Einführung
Alles, was Git über ein Repository weiß, lebt in .git/. Zu wissen, was jeder Eintrag ist, beseitigt das Geheimnis aus "Was ist gerade passiert?"-Diagnosen.
Top-Level-Layout
.git/
HEAD # symbolische Ref auf den aktuellen Branch
config # repository-lokale Konfiguration
description # von gitweb verwendet
index # die Staging Area
packed-refs # gepackte Branch- und Tag-Refs (optional)
hooks/ # Client-seitige Hook-Skripte
info/ # Excludes-Datei und andere repo-lokale Info
logs/ # Reflogs
objects/ # alle Objekte (lose + pack/)
refs/ # Branches, Tags, Remote-Tracking
worktrees/ # verlinkte Worktrees (falls vorhanden)
modules/ # .git-Verzeichnisse von Submodules
HEAD und Refs
cat .git/HEAD
ls .git/refs/heads
ls .git/refs/remotes/origin
ls .git/refs/tags
cat .git/packed-refs | head
objects/
Lose Objekte unter objects/xx/, gepackte Objekte in objects/pack/. Nicht von Hand anfassen.
logs/
Das Reflog. logs/HEAD zeichnet jede Bewegung von HEAD auf; logs/refs/heads/<branch> zeichnet die Historie jedes Branches auf.
cat .git/logs/HEAD | head
hooks/
Beispiel-Hook-Skripte, alle standardmäßig *.sample benannt. Zum Aktivieren entfernen Sie das Suffix und machen es ausführbar:
cd .git/hooks
cp pre-commit.sample pre-commit
chmod +x pre-commit
info/
info/exclude ist eine pro-Repo-, pro-Klon-Ignore-Datei (nicht committet). info/refs wird von git update-server-info für dumme HTTP-Server generiert.
config
Lokale Konfiguration im INI-Format. Bearbeiten via git config --local oder git config -e:
cat .git/config
git config --local user.email "[email protected]"
worktrees/
Jeder verlinkte Worktree hat ein Verzeichnis unter .git/worktrees/<name>/ mit eigenen HEAD, index und logs.
modules/
Bei Repositories mit Submodules lebt das .git-Verzeichnis jedes Submodules hier, und der Working Tree des Submodules enthält eine kleine .git-Datei, die darauf zeigt.
Bare-Repositories
Ein Bare-Repository hat denselben Inhalt, aber auf der obersten Ebene (kein .git/-Wrapper) und ohne Working Tree. Konvention: das Verzeichnis project.git nennen.
git rev-parse für Pfade
Skripte, die Pfade innerhalb von .git/ finden müssen, sollten niemals annehmen, dass das Verzeichnis buchstäblich .git heißt. Submodules verwenden eine .git-Datei, die woanders hin zeigt; Worktrees haben verlinkte Gitdirs; Bare-Repositories haben kein separates Gitdir. Verwenden Sie git rev-parse:
git rev-parse --git-dir # tatsächliches Gitdir für aktuelles Repository
git rev-parse --git-common-dir # geteiltes Verzeichnis für Worktrees
git rev-parse --show-toplevel # Wurzel des Working Trees
git rev-parse --is-inside-git-dir
git rev-parse --is-inside-work-tree
Diese fünf Fragen decken nahezu jede "Wo bin ich?"-Prüfung ab, die ein Skript braucht.
Häufige Fehler
Dateien innerhalb von .git/ direkt editieren. Fast für alles gibt es einen Git-Befehl, der es korrekt, atomar und mit Hooks erledigt. Nur den Working Tree sichern und vergessen, dass .git/ die gesamte Historie enthält; sichern Sie das ganze Verzeichnis. .git/hooks/ teilen in der Annahme, sie würden sich verbreiten; Hooks sind nicht versioniert. Verwenden Sie core.hooksPath oder ein Tool wie pre-commit, um sie zu teilen. Schließlich: .git/index impulsiv löschen; bauen Sie ihn mit git read-tree HEAD neu, aber nur nach einem Backup.