Git-Repository beschädigt (falsche Header-Prüfung; loses Objekt ist beschädigt)

74

Ich habe gestern Abend einen Stromausfall erlebt, als ich eine Commit-Nachricht geschrieben habe. Beim Booten des Computers konnte ich das Commit nicht abschließen. Ich lief git reset, fügte die geänderten Dateien wieder hinzu und versuchte es erneut und bekam Folgendes:

% git commit
error: inflate: data stream error (incorrect header check)
error: unable to unpack a94406345ac44982b00cf57b4b9660a35436637f header
fatal: a94406345ac44982b00cf57b4b9660a35436637f is not a valid object

git fsck zeigt Folgendes:

% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack 4346883490a0990e68db0187241abc1642765a73 header
error: inflate: data stream error (incorrect header check)
fatal: loose object 4346883490a0990e68db0187241abc1642765a73 (stored in .git/objects/43/46883490a0990e68db0187241abc1642765a73) is corrupt

Ich stelle fest, dass sich die Nachrichten über verschiedene Objekte beschweren.

Ich suchte SO und das Web und versuchte ein paar verschiedene Dinge, aber ohne Erfolg.

  • Ich habe keine aktuelle Sicherungskopie.
  • Das Klonen des Repositorys in ein anderes Verzeichnis hilft nicht. Das neue Repository weist genau die gleichen Probleme auf.
  • git stashgibt die gleiche Nachricht wie git commit. Alle anderen Git-Befehle scheinen normal zu funktionieren.

Wie kann ich feststellen, was falsch ist, und es beheben?

Bearbeiten: git log Ausgabe wie vorgeschlagen (nur die ersten Zeilen):

% git log --oneline --decorate --all |head -n 8
253b086 (HEAD, new_tokenize) Normalized tokenizer interface slightly
0f2425a (master) Added procs to eval layer
a4d4c22 Added procedures as a type
d1e15ad (tag: v0.10) Added `if' form with tail call semantics
f94a992 (tag: v0.9) Completed environments
031116e Fixed bug where # on a line by itself caused segfault
3d8b09f Added environments, define and set!
01cc624 Put symbol table implementation into types.c

Dies ist ein kleines persönliches Projekt; Normalerweise arbeite ich nur in (Master), aber ich habe zu der Zeit ein Experiment durchgeführt (new_tokenize). 253b086 war das letzte erfolgreiche Commit vor dem Stromausfall.

trentcl
quelle
vielleicht versuchen Sie ein git logoder git log --oneline --decorate --allzu sehen, wie die Geschichte aussieht
jkyako
Erledigt. Sie sind sich nicht sicher, wonach Sie genau suchen. Lassen Sie mich wissen, ob Sie die volle Ausgabe wünschen oder was. Ich habe nichts
Besonderes gemacht
Meistens nur um herauszufinden, was angesichts der gemeldeten beschädigten Objekte letztendlich verloren geht / nicht zugänglich ist. Angenommen, Sie haben nicht festgeschriebene lokale Änderungen an einem anderen Ort gespeichert. Können Sie dann git checkoutjede der im Protokoll aufgeführten IDs ändern ? Ich frage mich, ob eine Brute-Force-Lösung darin besteht, die einzelnen IDs zu skripten, die ID zu überprüfen und den Arbeitsbaum an eine andere Stelle (möglicherweise in ein neues Git-Repository) zu kopieren, um zu versuchen, ein nicht korruptes Repo neu zu erstellen.
Jkyako
3
Lesen Sie einfach diesen Beitrag und denken Sie, dass es interessant sein könnte, die beschädigten Objekte vorübergehend an einen anderen Ort zu verschieben und erneut zu versuchen git fsck --full, um herauszufinden, was aktuell auf die fehlerhaften Objekte verweist.
Jkyako
1
Danke @jkyako, das hat mich auf den richtigen Weg gebracht. Die Antwort steht bevor.
Trentcl

Antworten:

72

Es scheint, dass git Dateien in .git / objects für das neue Commit erstellt hat, aber nicht erfolgreich darauf geschrieben hat. Ich habe es gelöst, indem ich sie einzeln gelöscht und erneut ausgeführt habe git fsck --full, um die nächste zu finden. Ich habe mit dem angefangen, von dem ursprünglich berichtet wurde git fsck:

% rm -f .git/objects/43/46883490a0990e68db0187241abc1642765a73
% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack 86e7247af5865e857a3b61eed99986e2d9538df1 header
error: inflate: data stream error (incorrect header check)
fatal: loose object 86e7247af5865e857a3b61eed99986e2d9538df1 (stored in .git/objects/86/e7247af5865e857a3b61eed99986e2d9538df1) is corrupt
% rm -f .git/objects/86/e7247af5865e857a3b61eed99986e2d9538df1
% git fsck --full
Checking object directories: 100% (256/256), done.
error: inflate: data stream error (incorrect header check)
error: unable to unpack a94406345ac44982b00cf57b4b9660a35436637f header
error: inflate: data stream error (incorrect header check)
fatal: loose object a94406345ac44982b00cf57b4b9660a35436637f (stored in .git/objects/a9/4406345ac44982b00cf57b4b9660a35436637f) is corrupt

Und so weiter. Ich habe fünf Objekte gelöscht, bevor git fscksie sauber angezeigt wurden. Dies entspricht (wie ich vermute) den fünf Dateien in dem Commit, das ich erstellen wollte. Ich denke, dass der Dateiversionsverlauf überhaupt nicht beschädigt wurde.

Übrigens dachte ich an eine andere Methode, die auch zu funktionieren scheint. git clonekopiert die fehlerhaften Objekte, git pushtut dies aber nicht. Nach dem Sichern habe ich ein neues leeres Repository erstellt (--bare, da Sie sonst nicht zum Master pushen können), dann meine Änderungen aufgehoben und beide Zweige in das neue Repository verschoben. Dann ging es nur noch darum, es erneut zu überprüfen und die neuesten Änderungen aus meinen Backups wiederherzustellen.

Immer noch interessiert, ob jemand hier Licht in den Fehlermechanismus bringen möchte.

trentcl
quelle
2
Auch nach diesen Schritten tun del .git\indexundgit reset
Ozba
@ozba Bitte näher erläutern. Wenn es einen Grund dafür gibt, werde ich ihn meiner Antwort hinzufügen, aber in meinem Fall war er nicht notwendig.
Trentcl
Es war in meinem Fall notwendig, da der Index auch beschädigt war
Ozba
@ozba Wie können Sie feststellen, ob der Index in einer solchen Situation beschädigt ist? Gibt es einen zusätzlichen oder etwas anderen Fehler?
Trentcl
Ja, wenn Sie zum Beispiel den Git-Status auch nach all den von Ihnen dargestellten Schritten ausführen, heißt es immer noch, dass das Objekt XXX nicht gelesen werden kann.
Ozba
9

Einfache Antwort auf diese Frage für alle, die mit diesem Problem konfrontiert sind: Der Befehl git clone ist die Lösung. Wenn Sie ein Remote-Repo haben, klonen Sie es in den lokalen Ordner (nachdem Sie das beschädigte lokale Repo gelöscht haben), falls Sie kein Remote-Repo haben, und versuchen Sie es dann Schieben Sie das beschädigte Repo auf Github und klonen Sie es dann von dort. Ich denke, dass beschädigte Objekte nicht verschoben werden und das Problem dadurch behoben wird

Zu cool
quelle
7
Es könnte das Problem "beheben", aber Sie werden die beschädigten Dateien verlieren.
Lawrence Dol
Ich habe versucht, die akzeptierte Antwort zu finden, aber es hat bei mir nicht funktioniert, aber wincent.com/wiki/Dealing_with_Git_repo_corruption hat funktioniert und ähnelt Ihrer Meinung - mit der großen Einschränkung, dass es den Überblick über lokale Niederlassungen verliert - hatte ich das Glück, dass ich auf eine Fernbedienung geschoben habe Verzweigen Sie, bevor die Dateien beschädigt wurden, da ich die Änderungen nach dem Klonen einfach abrufen konnte
Nathan Beck
8

Wie in dieser Antwort beschrieben, lief ich:

git reflog expire --expire-unreachable=now --all
git gc --prune=now

Dadurch wurden alle meine baumelnden Blobs und baumelnden Commits sowie die beschädigten DB-Objekte entfernt.

Es war viel schneller, als sie einzeln aufzuspüren!

BitBot
quelle
13
git gc --prune = gibt mir jetzt nur den gleichen Fehler
bezüglich