git fsck: Repository-Integrität prüfen und Datenkorruption erkennen
AI generated
git
HEAD
Git · Repository-Wartung
git fsck
Repository-Integrität prüfen und Datenkorruption rechtzeitig erkennen

Git gilt gemeinhin als robust, weil jedes Objekt über seinen Inhalts-Hash identifiziert wird, doch auch eine Objektdatenbank aus SHA-Hashes ist nicht immun gegen defekte Festplatten, abgebrochene Prozesse oder versehentlich gelöschte Dateien. Das eingebaute Kommando git fsck durchsucht genau diese Objektdatenbank nach Inkonsistenzen und macht Probleme sichtbar, bevor sie zu echtem, irreversiblem Datenverlust führen. Dieser Artikel erklärt, was fsck tatsächlich prüft, wie die häufigsten Fehlermeldungen zu lesen sind und mit welchen Schritten sich ein beschädigtes Repository reparieren lässt.

9 Min. Lesezeit Git Repository-Wartung

1. Was git fsck tatsächlich prüft

Jedes Objekt in Git, ob Blob, Tree, Commit oder Tag, wird über einen Hash seines Inhalts identifiziert und in der Objektdatenbank unter .git/objects abgelegt. git fsck, ausgeschrieben file system check, liest diese Objekte, berechnet ihren Hash erneut und vergleicht ihn mit dem Dateinamen, unter dem das Objekt gespeichert ist. Weichen beide voneinander ab, ist das ein klares Zeichen für Korruption, denn in einem intakten Repository muss der Inhalt eines Objekts exakt zu seinem Hash passen.

Zusätzlich prüft fsck die Verweisstruktur zwischen Objekten: Zeigt ein Commit auf einen Tree, der nicht existiert, oder verweist ein Tree-Eintrag auf einen fehlenden Blob, meldet fsck das als broken link. Das Kommando arbeitet dabei rein lesend, es verändert das Repository nicht, sondern liefert ausschliesslich einen Befund, auf dessen Basis dann gezielt repariert werden kann.


# Grundlegende Integritätsprüfung
git fsck

# Gründlichere Prüfung inklusive gepackter Objekte
git fsck --full

# Auch unreferenzierte Objekte mit ausgeben
git fsck --full --unreachable --dangling

2. Häufige Fehlermeldungen richtig einordnen

Die Ausgabe von fsck unterscheidet klar zwischen echten Fehlern und reinen Hinweisen. dangling commit bedeutet, dass ein Commit existiert, auf den kein Branch, Tag oder anderer Verweis mehr zeigt, meist entstanden durch git reset --hard, gelöschte Branches oder einen abgebrochenen Rebase. Solche Commits sind nicht kaputt, sie sind lediglich nicht mehr erreichbar und werden nach einer gewissen Zeit vom Garbage Collector entfernt.

unreachable object beschreibt ähnliches für Blobs und Trees, die von keinem erreichbaren Commit mehr referenziert werden. Deutlich ernster ist missing blob oder missing tree, hier fehlt ein Objekt vollständig, obwohl ein anderes Objekt darauf verweist, ein klares Zeichen für Datenverlust. Am kritischsten ist error: sha1 mismatch, das bedeutet, ein gespeichertes Objekt hat einen anderen Inhalt, als sein Dateiname erwarten lässt, also echte Bit-Korruption.

3. Wie Korruption in der Objektdatenbank überhaupt entsteht

Plötzliche Stromausfälle oder harte Prozessabbrüche während Git gerade Objekte in .git/objects schreibt, gehören zu den häufigsten Ursachen, besonders auf Systemen ohne journaling Dateisystem oder bei defekten SSDs. Ebenso riskant ist eine vollgelaufene Festplatte, wenn Git mitten im Schreiben eines Pack-Files abbricht, weil kein Speicherplatz mehr frei ist.

Auch manuelle Eingriffe direkt im .git-Verzeichnis, etwa das Verschieben oder Löschen einzelner Objektdateien durch ein unbedachtes Aufräum-Skript, führen zuverlässig zu Inkonsistenzen. Bei Netzwerklaufwerken oder synchronisierten Cloud-Ordnern, in denen ein .git-Verzeichnis liegt, kann zudem ein Konflikt zwischen zwei gleichzeitig schreibenden Prozessen einzelne Objektdateien beschädigen, weshalb Git-Repositories grundsätzlich nicht in automatisch synchronisierten Ordnern liegen sollten.

4. Wichtige Optionen im Detail

Ohne zusätzliche Parameter prüft fsck nur lose Objekte, also solche, die noch nicht in ein Pack-File komprimiert wurden. Die Option --full bezieht auch gepackte Objekte in die Prüfung mit ein und sollte deshalb bei jeder ernsthaften Diagnose gesetzt werden. --strict aktiviert zusätzliche, strengere Konsistenzregeln, etwa zur korrekten Formatierung von Tree-Einträgen, und deckt damit auch subtilere Probleme auf.

--unreachable listet Objekte, die von keinem Branch oder Tag mehr erreicht werden, während --dangling gezielt Objekte ohne jeglichen eingehenden Verweis anzeigt, das sind häufig genau die Commits, die nach einem versehentlichen Reset wiederhergestellt werden sollen. Mit --lost-found schreibt fsck gefundene dangling Objekte zusätzlich in das Verzeichnis .git/lost-found, von wo sie sich einfacher weiterverarbeiten lassen.


# Strengere Prüfung mit Ablage gefundener dangling Objekte
git fsck --full --strict --lost-found

# Gefundene dangling Commits inspizieren
git show <commit-hash>

# Einen gefundenen Commit als neuen Branch retten
git branch geretteter-stand <commit-hash>

5. Reparaturstrategien nach einem positiven fsck-Befund

Bei blossen dangling oder unreachable Objekten besteht in der Regel kein Handlungsbedarf, sie sind ein normaler Nebeneffekt der Git-Nutzung und werden früher oder später automatisch entfernt. Anders sieht es bei echten missing oder corrupt Objekten aus: Hier hilft zunächst ein Blick in ein Backup oder ein anderes Klon desselben Repositories, denn Git-Objekte sind inhaltsadressiert, ein identisches Objekt aus einem anderen, intakten Repository lässt sich einfach in .git/objects zurückkopieren.

Steht kein Backup zur Verfügung, aber es gibt einen aktuellen Remote, ist ein frischer Clone von dort oft der pragmatischste Weg, weil dabei die komplette Objektdatenbank neu und garantiert konsistent übertragen wird. Nur wenn das betroffene Objekt ausschliesslich lokal existierte und nirgendwo sonst vorliegt, ist es tatsächlich unwiederbringlich verloren, ein Grund mehr, wichtige Commits zeitnah zu pushen.

6. Das Reflog als eingebautes Sicherheitsnetz

Bevor fsck überhaupt nötig wird, lohnt sich bei verloren geglaubten Commits zunächst ein Blick ins Reflog, das lokal protokolliert, wohin HEAD und jeder Branch in den letzten Wochen gezeigt haben. git reflog listet diese Historie chronologisch und macht Commits sichtbar, die durch einen Reset, eine gelöschte Branch-Referenz oder einen fehlgeschlagenen Rebase scheinbar verschwunden sind, tatsächlich aber noch als dangling Objekte in der Datenbank liegen.

Das Reflog ist rein lokal und wird standardmäßig nach 90 Tagen für erreichbare und nach 30 Tagen für nicht mehr erreichbare Einträge bereinigt, ein enges Zeitfenster im Vergleich zu einer echten Backup-Strategie, aber für die meisten versehentlichen Verluste innerhalb weniger Tage oder Wochen vollkommen ausreichend.


# Lokale Historie von HEAD und Branches durchsuchen
git reflog show HEAD

# Verlorenen Stand wiederherstellen
git checkout -b wiederhergestellt HEAD@{5}

7. Integritätsprüfung automatisieren

Für kritische Repositories, insbesondere zentrale Bare-Repositories auf einem selbst gehosteten Git-Server, lohnt sich eine regelmäßige, automatisierte fsck-Prüfung über einen Cronjob, kombiniert mit einer Benachrichtigung, sobald die Ausgabe echte Fehler statt nur harmloser dangling-Hinweise enthält. Ein einfaches Skript kann dabei zwischen den beiden Fällen unterscheiden, indem es gezielt nach Zeilen mit missing, corrupt oder sha1 mismatch filtert.

In größeren Infrastrukturen ergänzt eine solche Prüfung idealerweise ein bestehendes Backup-Regime, denn fsck erkennt Probleme, behebt sie aber nicht automatisch, die eigentliche Wiederherstellung braucht immer eine intakte Kopie der betroffenen Objekte von irgendwo.


#!/bin/bash
# Einfache fsck-Prüfung für Cronjobs, meldet nur echte Fehler
OUTPUT=$(git fsck --full 2>&1)
if echo "$OUTPUT" | grep -qE "missing|corrupt|sha1 mismatch"; then
  echo "Kritischer fsck-Befund im Repository:" >&2
  echo "$OUTPUT" >&2
  exit 1
fi

8. Praxisbeispiel: korruptes Repository nach einem Server-Crash

Nach einem unerwarteten Stromausfall auf einem Build-Server meldete git status plötzlich fatal: loose object is corrupt. Ein erster git fsck --full bestätigte genau ein defektes Blob-Objekt, alle anderen Objekte waren unauffällig. Da das Repository regelmäßig zu einem zentralen GitLab-Server gepusht wurde, reichte ein einfacher git fetch gefolgt vom Kopieren der entsprechenden Objektdatei aus einem frischen Klon in das lokale .git/objects-Verzeichnis, um den Build-Server wieder lauffähig zu machen.

Wäre kein Remote verfügbar gewesen, hätte nur ein vollständiger Neuklon aus einem intakten Backup geholfen. Der Vorfall zeigte einmal mehr, dass ein lokal isoliertes Repository ohne Remote im Ernstfall keine Wiederherstellungsoption bietet, ganz gleich wie sorgfältig committet wurde.

9. Prävention: Backups, Bare-Mirrors und regelmäßige Checks

Der wirksamste Schutz vor Datenverlust ist nicht fsck selbst, sondern eine konsequente Push-Disziplin gegen mindestens ein Remote-Repository, idealerweise ergänzt um ein separates Bare-Mirror auf einem zweiten Server. Ein Bare-Repository ohne Arbeitsverzeichnis lässt sich einfach per Cronjob mit git remote update aktuell halten und dient als zusätzliche, unabhängige Kopie der kompletten Objektdatenbank.

Auf Entwickler-Maschinen gehört regelmäßiges, automatisches Pushen von Feature-Branches ebenfalls zur Prävention, weil lokale, nie gepushte Commits im Korruptionsfall die einzigen sind, die tatsächlich verloren gehen können. Ein monatlicher fsck-Lauf auf zentralen Servern rundet die Strategie ab und macht schleichende Probleme sichtbar, bevor sie zu einem echten Vorfall werden.

Fehlertyp Bedeutung Typische Ursache Massnahme
dangling commit Commit ohne eingehenden Verweis Reset, gelöschter Branch, Rebase Meist unkritisch, bei Bedarf per Branch retten
unreachable object Blob/Tree ohne erreichbaren Pfad Amend, Rebase, Squash Unkritisch, wird später per gc entfernt
missing blob/tree Referenziertes Objekt fehlt vollständig Gelöschte Objektdatei, Uebertragungsfehler Aus Backup oder intaktem Klon wiederherstellen
sha1 mismatch Inhalt passt nicht zum Hash Bit-Korruption, defekte Hardware Objekt aus Remote/Backup ersetzen, Hardware prüfen

Mironsoft

Git-Workflows, Branching-Strategien und CI-Hooks

Chaotische Git-Historie und unklare Branching-Regeln im Team?

Wir richten saubere Git-Workflows ein, klären Branching-Strategien fürs Team und automatisieren Qualitätschecks über Git-Hooks und CI-Pipelines, damit die Historie nachvollziehbar bleibt.

Workflow-Audit

Bestehende Branching-Strategie und Merge-Praxis auf Schwachstellen prüfen.

Hook-Automatisierung

Pre-Commit- und Pre-Push-Hooks für Linting, Tests und Commit-Konventionen einrichten.

Team-Schulung

Rebase, Cherry-Pick und Konfliktauflösung im Team praxisnah vermitteln.

10. Zusammenfassung

git fsck: Das Wichtigste auf einen Blick

Zweck

Prüft, ob gespeicherte Objekte zu ihrem Hash passen und alle Verweise auflösbar sind

Wichtigste Option

git fsck --full bezieht auch gepackte Objekte in die Prüfung mit ein

Erste Anlaufstelle

Bei verloren geglaubten Commits zuerst git reflog prüfen, nicht direkt fsck

Prävention

Regelmäßiges Pushen und ein separates Bare-Mirror sind wirksamer als Reparatur im Nachhinein

11. FAQ: git fsck: Das Wichtigste auf einen Blick

1Was genau prüft git fsck?
git fsck berechnet den Hash jedes gespeicherten Objekts neu und vergleicht ihn mit dem Dateinamen, unter dem es abgelegt ist, und prüft zusätzlich, ob alle Verweise zwischen Commits, Trees und Blobs auf tatsächlich vorhandene Objekte zeigen.
2Ist ein dangling commit ein Fehler, den ich beheben muss?
Nein, ein dangling commit ist lediglich ein Commit ohne eingehenden Verweis, meist durch Reset oder einen gelöschten Branch entstanden. Er wird nach einer gewissen Zeit automatisch per Garbage Collection entfernt und stellt keine Korruption dar.
3Was bedeutet die Meldung sha1 mismatch?
Diese Meldung zeigt echte Bit-Korruption an: Der tatsächliche Inhalt eines gespeicherten Objekts stimmt nicht mehr mit dem Hash überein, unter dem es abgelegt wurde. Das deutet meist auf defekte Hardware oder ein abgebrochenes Schreiben hin.
4Warum sollte ich --full bei git fsck verwenden?
Ohne --full prüft fsck nur lose, noch nicht gepackte Objekte. Ein Grossteil der Objekte in einem gepflegten Repository liegt aber in Pack-Files, die erst mit --full in die Prüfung einbezogen werden.
5Kann git fsck ein korruptes Repository automatisch reparieren?
Nein, fsck liefert nur einen Befund. Die eigentliche Reparatur erfordert eine intakte Kopie der betroffenen Objekte aus einem Backup, einem Remote-Repository oder einem anderen Klon.
6Was ist der Unterschied zwischen fsck und dem Reflog für die Fehlersuche?
Das Reflog protokolliert, wohin HEAD und Branches lokal gezeigt haben, und hilft bei versehentlich verlorenen, aber technisch intakten Commits. fsck dagegen prüft die technische Konsistenz der Objektdatenbank und findet auch echte Datenkorruption.
7Wie lange bleiben dangling Objekte im Repository erhalten?
Standardmäßig entfernt git gc unreachable Objekte nach 30 Tagen und Reflog-Einträge für nicht mehr erreichbare Commits ebenfalls nach etwa 30 Tagen, erreichbare Reflog-Einträge nach 90 Tagen, die genauen Werte lassen sich über gc.pruneExpire konfigurieren.
8Sollte ich git fsck regelmäßig automatisiert ausführen?
Bei zentralen, geschäftskritischen Bare-Repositories auf einem eigenen Git-Server ist ein regelmäßiger, automatisierter fsck-Lauf sinnvoll, kombiniert mit einer Benachrichtigung bei echten Fehlermeldungen statt nur harmlosen dangling-Hinweisen.
9Kann ein synchronisierter Cloud-Ordner ein Git-Repository beschädigen?
Ja, wenn zwei Prozesse gleichzeitig in dasselbe .git-Verzeichnis schreiben, etwa weil es über einen Cloud-Sync-Ordner auf zwei Geräten aktiv ist, können einzelne Objektdateien inkonsistent geschrieben werden. Git-Repositories sollten grundsätzlich nicht in solchen Ordnern liegen.
10Was ist der beste Schutz gegen Datenverlust durch Repository-Korruption?
Konsequentes, regelmäßiges Pushen gegen mindestens ein Remote-Repository, idealerweise ergänzt um ein separates Bare-Mirror auf einem zweiten Server, schützt zuverlässiger als jede nachträgliche Reparatur mit fsck.