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

Einführung

Objekte sind unveränderlich und durch Hash benannt. Referenzen sind die veränderlichen, menschenlesbaren Namen, die auf sie zeigen. Jeder Branch, Tag, Remote-Tracking-Branch und HEAD ist eine Ref.

Wo Refs leben

Refs sind Dateien (oder Einträge in der packed-refs-Datei) unter .git/refs/:

  • .git/refs/heads/<name>: lokale Branches.
  • .git/refs/tags/<name>: Tags.
  • .git/refs/remotes/<remote>/<name>: Remote-Tracking-Branches.
  • .git/HEAD: die aktuelle Ref.

Jede nicht-symbolische Ref ist eine einzeilige Datei mit einem Hash:

cat .git/refs/heads/main
# a1b2c3d4...

Refs auflisten

git for-each-ref
git for-each-ref refs/tags/
git for-each-ref --format='%(refname:short) %(objectname:short) %(subject)'
git show-ref

Symbolische Refs

Eine symbolische Ref zeigt auf eine andere Ref statt auf einen Hash. HEAD ist das kanonische Beispiel:

cat .git/HEAD
# ref: refs/heads/main
git symbolic-ref HEAD
git symbolic-ref refs/remotes/origin/HEAD

Refs sicher lesen

Verwenden Sie immer Plumbing, anstatt Dateien zu lesen:

git rev-parse HEAD
git rev-parse main
git rev-parse origin/main
git rev-parse v1.0.0^{commit}

Plumbing handhabt packed Refs, symbolische Refs und Ref-Lookups einheitlich.

Refs aktualisieren

git update-ref refs/heads/feature/login <sha>
git update-ref -d refs/heads/feature/login           # löschen
git update-ref refs/heads/feature/login <new> <old> # CAS

Die Drei-Argumente-Form ist Compare-and-Set; sie verweigert, wenn der aktuelle Wert abweicht.

Packed Refs

Aus Performance-Gründen kann Git viele Refs in eine einzige .git/packed-refs-Datei packen. git pack-refs --all tut dies; künftige Schreibvorgänge gehen weiterhin in lose Dateien, bis zum nächsten Pack.

Refspec-Syntax

Remotes verwenden Refspecs, um zwischen lokalen und Remote-Refs abzubilden:

+refs/heads/*:refs/remotes/origin/*

Das führende + bedeutet "Force Update". Diese eine Zeile ist es, was git fetch dazu bringt, refs/remotes/origin/ zu befüllen.

Das Reftable-Backend

Modernes Git (2.45+) liefert ein alternatives Ref-Speicherformat namens Reftable, ursprünglich für JGit entwickelt. Reftable speichert Millionen Refs effizient in einem binären log-strukturierten Format und unterstützt atomare Transaktionen über viele Refs hinweg. Aktivieren auf einem neuen Repository:

git init --ref-format=reftable
git rev-parse --show-ref-format

Für die meisten Nutzer ist das klassische lose+packed-Format weiterhin in Ordnung. Reftable glänzt auf Servern und auf riesigen Monorepos mit Hunderttausenden Refs (z. B. eine Ref pro Pull Request).

Eigene Ref-Hierarchien

Refs müssen nicht unter den vier Standard-Namespaces leben. Tools, die eigene Namen brauchen, verwenden eigene Hierarchien unter refs/:

  • refs/notes/*: git notes.
  • refs/stash: git stash.
  • refs/replace/*: git replace.
  • refs/bisect/*: git bisect-Status.
  • refs/pull/*/head und refs/merge-requests/*/head: Hosting-Anbieter.
git for-each-ref refs/notes/
git for-each-ref refs/replace/

Sie können eigene erstellen, solange der Name eine gültige Ref ist (keine doppelten Punkte, keine Leerzeichen, kein führender Bindestrich).

Häufige Fehler

Ref-Dateien manuell editieren und mit einem Trailing-Newline-Problem oder einer halb geschriebenen Datei enden. Verwenden Sie git update-ref. refs/heads/main, main und refs/main verwechseln; git rev-parse --symbolic-full-name löst jeden Kurznamen zu seiner kanonischen Form auf. Einen Branch und einen Tag identisch benennen; Tools bevorzugen dann den Tag, was zu subtiler Verwirrung führt. Schließlich: .git/packed-refs löschen, um "aufzuräumen"; das löscht Refs, die nicht auch lose sind. Gehen Sie immer über Git.