Skip to main content

Das Reflog – deine Lebensversicherung bei Git-Unfällen 🛟

Das Reflog (Reference Log) ist eines der mächtigsten, aber am wenigsten bekannten Features von Git. Es ist buchstäblich dein Sicherheitsnetz, das dich vor fast jedem Git-Unfall retten kann – selbst wenn du denkst, du hättest Commits unwiederbringlich verloren.


Was genau ist das Reflog?

Das Reflog ist ein lokales Protokoll aller Bewegungen von Referenzen (insbesondere HEAD) in deinem Repository. Jedes Mal, wenn sich HEAD bewegt – sei es durch einen Commit, Checkout, Reset, Rebase, Merge oder irgendeinen anderen Befehl – wird ein Eintrag im Reflog erstellt.

Der entscheidende Unterschied zur normalen Historie

Die normale Git-Historie (die du mit git log siehst) zeigt dir nur die Commits, die von deinem aktuellen Branch aus erreichbar sind. Das Reflog hingegen protokolliert jede Zustandsänderung, unabhängig davon, ob die entsprechenden Commits noch von einem Branch referenziert werden oder nicht.

Stell dir das Reflog wie eine Zeitmaschine vor: Es merkt sich nicht nur, wo du jetzt bist, sondern auch jeden Ort, an dem du jemals warst – selbst wenn der Weg dorthin inzwischen „verschwunden" zu sein scheint.

Was wird im Reflog gespeichert?

Jeder Reflog-Eintrag enthält folgende Informationen:

  • SHA-1-Hash des Commits, auf den HEAD zu diesem Zeitpunkt zeigte
  • Aktion, die die Bewegung ausgelöst hat (commit, checkout, reset, rebase, merge, etc.)
  • Zeitstempel der Aktion
  • Nachricht mit zusätzlichen Details (z.B. Commit-Message oder Branch-Name)

Warum ist das Reflog deine „Lebensversicherung"? 🆘

In Git gibt es viele Situationen, in denen du denkst, du hättest Daten verloren:

  1. Harter Reset: Du führst git reset --hard HEAD~5 aus und merkst, dass du die falschen Commits gelöscht hast
  2. Fehlgeschlagener Rebase: Ein Interactive Rebase geht schief und deine Commits scheinen verschwunden
  3. Branch gelöscht: Du löschst versehentlich einen Branch, der noch nicht gemergt war
  4. Falscher Checkout: Du wechselst den Branch und hast vergessen, Änderungen zu committen
  5. Amend-Unfall: Du machst git commit --amend und überschreibst versehentlich einen wichtigen Commit

In all diesen Fällen gilt: Die Commits sind nicht wirklich weg! Sie sind nur nicht mehr von einem Branch aus erreichbar. Das Reflog hat sie jedoch noch protokolliert und kennt ihre SHA-1-Hashes.

Die 90-Tage-Regel

Git behält Reflog-Einträge standardmäßig 90 Tage lang (für erreichbare Commits) bzw. 30 Tage (für nicht mehr erreichbare Commits). Erst danach werden sie bei einer Garbage Collection (git gc) endgültig entfernt. Du hast also ein großzügiges Zeitfenster, um Fehler zu korrigieren.


Das Reflog in der Praxis – Kommandozeile

Grundlegender Befehl

git reflog

Dieser Befehl zeigt dir die letzten Bewegungen von HEAD. Die Ausgabe sieht etwa so aus:

a1b2c3d (HEAD -> feature/login) HEAD@{0}: commit: Implementiere Login-Validierung
e4f5g6h HEAD@{1}: commit: Füge Login-Formular hinzu
i7j8k9l HEAD@{2}: checkout: moving from main to feature/login
m0n1o2p (main) HEAD@{3}: reset: moving to HEAD~3
q3r4s5t HEAD@{4}: commit: Wichtiger Commit den ich verloren glaubte
u6v7w8x HEAD@{5}: commit: Noch ein wichtiger Commit
y9z0a1b HEAD@{6}: commit: Der erste wichtige Commit

Die Reflog-Syntax verstehen

Die Notation HEAD@{n} ist eine spezielle Referenz-Syntax:

  • HEAD@{0} – der aktuelle Zustand von HEAD
  • HEAD@{1} – der vorherige Zustand von HEAD
  • HEAD@{2} – der Zustand davor
  • usw.

Du kannst diese Notation auch mit Zeitangaben verwenden:

git reflog HEAD@{1.hour.ago}
git reflog HEAD@{yesterday}
git reflog HEAD@{2024-01-15}

Detaillierte Reflog-Ansicht

Für mehr Details kannst du Optionen hinzufügen:

# Mit vollständigen Commit-Informationen
git reflog show --all

# Mit Datum und Uhrzeit
git reflog --date=iso

# Nur für einen bestimmten Branch
git reflog show feature/login

Praktische Rettungsszenarien mit dem Reflog

Szenario 1: Commits nach hartem Reset wiederherstellen

Du hast versehentlich einen harten Reset durchgeführt und wichtige Commits „verloren":

# Der fatale Befehl, der alles kaputt gemacht hat
git reset --hard HEAD~5

# Panik! Aber Ruhe bewahren – Reflog anschauen
git reflog

Die Ausgabe zeigt dir:

a1b2c3d (HEAD -> main) HEAD@{0}: reset: moving to HEAD~5
f8e9d0c HEAD@{1}: commit: Letzter wichtiger Commit
b2c3d4e HEAD@{2}: commit: Vorletzter wichtiger Commit
...

Jetzt kannst du zu dem Commit vor dem Reset zurückkehren:

# Entweder mit der Reflog-Referenz
git reset --hard HEAD@{1}

# Oder direkt mit dem SHA-Hash
git reset --hard f8e9d0c

Szenario 2: Gelöschten Branch wiederherstellen

Du hast einen Branch gelöscht und merkst zu spät, dass er wichtige Arbeit enthielt:

# Der Fehler
git branch -D feature/wichtig

# Reflog zeigt den letzten Commit des Branches
git reflog | grep "feature/wichtig"
# Ausgabe: a1b2c3d HEAD@{5}: checkout: moving from feature/wichtig to main

# Branch wiederherstellen
git checkout -b feature/wichtig a1b2c3d

Szenario 3: Nach fehlgeschlagenem Rebase zurück zum Ursprung

Ein Interactive Rebase ist schiefgegangen:

# Du hast das hier gemacht
git rebase -i HEAD~10
# Und dabei alles vermasselt...

# Reflog zeigt den Zustand vor dem Rebase
git reflog
# Ausgabe: 
# x1y2z3w (HEAD -> feature) HEAD@{0}: rebase (finish): ...
# ...
# a1b2c3d HEAD@{7}: rebase (start): checkout HEAD~10
# f8e9d0c HEAD@{8}: commit: Mein letzter sauberer Commit

# Zurück zum Zustand vor dem Rebase
git reset --hard HEAD@{8}

Szenario 4: Versehentlich überschriebenen Commit nach Amend wiederherstellen

Du hast git commit --amend benutzt und dabei den ursprünglichen Commit überschrieben:

git reflog
# Ausgabe:
# a1b2c3d (HEAD -> main) HEAD@{0}: commit (amend): Neue Message
# f8e9d0c HEAD@{1}: commit: Ursprüngliche Message die ich behalten wollte

# Der ursprüngliche Commit existiert noch und kann wiederhergestellt werden
git cherry-pick f8e9d0c
# Oder wenn du komplett zurück willst:
git reset --hard f8e9d0c

Das Reflog in PhpStorm nutzen 🖥️

PhpStorm bietet eine grafische Oberfläche für das Reflog, die besonders für visuelle Lerntypen hilfreich ist.

Methode 1: Über das Git-Log-Fenster

  1. Öffne das Git-Tool-Fenster (unten in PhpStorm) oder über View → Tool Windows → Git

  2. Im Log-Tab siehst du normalerweise die Commit-Historie. Klicke auf das Uhren-Symbol (🕐) oder suche nach der Option „Show Reflog" in den Filter-Optionen

  3. Alternativ kannst du im Suchfeld des Log-Fensters nach spezifischen Commits suchen, wenn du deren SHA-Hash aus dem Terminal-Reflog kennst

Methode 2: Über das Terminal in PhpStorm

  1. Öffne das Terminal in PhpStorm (View → Tool Windows → Terminal oder Alt+F12)

  2. Führe dort git reflog aus – du bekommst die gleiche Ausgabe wie im externen Terminal

  3. Vorteil: Du kannst SHA-Hashes direkt kopieren und in PhpStorms Git-Funktionen verwenden

Methode 3: „Reset Current Branch to Here" nutzen

Wenn du im Git-Log einen bestimmten Commit gefunden hast (auch einen, der nur noch im Reflog existiert), kannst du ihn wiederherstellen:

  1. Rechtsklick auf den Commit im Log-Fenster
  2. Wähle „Reset Current Branch to Here..."
  3. Wähle den Reset-Modus:
    • Soft: Behält alle Änderungen staged
    • Mixed: Behält Änderungen, aber unstaged
    • Hard: Verwirft alle Änderungen (Vorsicht!)

Methode 4: Cherry-Pick für einzelne Commits

Wenn du nur einen bestimmten „verlorenen" Commit wiederhaben möchtest:

  1. Finde den SHA-Hash im Reflog (Terminal: git reflog)
  2. In PhpStorm: Git → Uncommitted Changes → Cherry-Pick (oder über das Log-Fenster)
  3. Gib den SHA-Hash ein oder suche nach dem Commit

Methode 5: Branch aus Reflog-Commit erstellen

  1. Finde den SHA-Hash des gewünschten Commits
  2. Git → Branches → New Branch
  3. Im Dialog kannst du bei „Starting point" den SHA-Hash eingeben
  4. Damit erstellst du einen neuen Branch, der auf den „verlorenen" Commit zeigt

Das Reflog für verschiedene Referenzen

Das Reflog existiert nicht nur für HEAD, sondern für alle Referenzen in deinem Repository:

# Reflog für HEAD (Standard)
git reflog show HEAD

# Reflog für einen bestimmten Branch
git reflog show main
git reflog show feature/login

# Reflog für alle Referenzen
git reflog show --all

Dies ist besonders nützlich, wenn du wissen möchtest, wie sich ein bestimmter Branch im Laufe der Zeit entwickelt hat, auch über Resets und Force-Pushes hinweg.


Wichtige Einschränkungen des Reflogs ⚠️

Trotz seiner Mächtigkeit hat das Reflog einige Grenzen, die du kennen solltest:

Das Reflog ist lokal

Das Reflog wird nicht mit Remote-Repositories synchronisiert. Es existiert nur auf deinem lokalen Rechner. Das bedeutet:

  • Wenn du dein Repository neu klonst, ist das Reflog leer
  • Teammitglieder haben jeweils ihr eigenes, unabhängiges Reflog
  • Du kannst das Reflog nicht nutzen, um Commits wiederherzustellen, die du nie lokal hattest

Zeitliche Begrenzung

Reflog-Einträge werden nach einer gewissen Zeit gelöscht:

# Standard-Einstellungen anzeigen
git config gc.reflogExpire          # Standard: 90 Tage
git config gc.reflogExpireUnreachable   # Standard: 30 Tage

# Falls gewünscht: Längere Aufbewahrung konfigurieren
git config gc.reflogExpire "180 days"
git config gc.reflogExpireUnreachable "90 days"

Garbage Collection beachten

Wenn git gc (Garbage Collection) läuft, können alte, nicht mehr referenzierte Commits tatsächlich gelöscht werden – aber nur, wenn sie auch aus dem Reflog abgelaufen sind:

# Manuelle Garbage Collection (normalerweise nicht nötig)
git gc

# Aggressive GC (kann alte Commits entfernen!)
git gc --aggressive --prune=now

Fortgeschrittene Reflog-Techniken

Commits in einem Zeitraum finden

# Alle Reflog-Einträge der letzten 2 Stunden
git reflog --since="2 hours ago"

# Reflog-Einträge zwischen zwei Zeitpunkten
git reflog --since="2024-01-01" --until="2024-01-15"

Reflog mit Diff kombinieren

Du kannst dir anschauen, was sich zwischen zwei Reflog-Zuständen geändert hat:

# Diff zwischen aktuellem Zustand und Zustand vor 5 Aktionen
git diff HEAD@{5} HEAD@{0}

# Welche Dateien haben sich geändert?
git diff --name-only HEAD@{5} HEAD@{0}

Reflog-Einträge als Grundlage für Branches

# Branch erstellen, der auf einen Reflog-Zustand zeigt
git branch recovery-branch HEAD@{10}

# Direkt zu einem Reflog-Zustand wechseln
git checkout HEAD@{10}  # Achtung: Detached HEAD!

Zusammenfassung – Dein Reflog-Notfall-Spickzettel 📋

Situation Lösung
Commits nach reset --hard verloren git reflog → SHA finden → git reset --hard <SHA>
Branch versehentlich gelöscht git reflog → letzten Commit des Branches finden → git checkout -b <branch-name> <SHA>
Rebase schiefgegangen git reflog → Zustand vor Rebase finden → git reset --hard HEAD@{n}
Commit nach Amend überschrieben git reflog → ursprünglichen Commit finden → git cherry-pick <SHA>
Wissen, was man vor X Stunden gemacht hat git reflog --since="X hours ago"

Das Wichtigste zum Schluss: Wenn etwas schiefgeht, keine Panik! Solange du nicht git gc --prune=now ausführst oder das Repository löschst, sind deine Commits mit sehr hoher Wahrscheinlichkeit noch da. Das Reflog ist dein Freund – lerne es kennen, bevor du es brauchst! 🛟