web-dev-qa-db-fra.com

Dépôt Git corrompu (vérification d'en-tête incorrecte; un objet desserré est corrompu)

J'ai eu une coupure de courant hier soir en écrivant un message de validation. Lorsque j'ai démarré la sauvegarde de la machine, je n'ai pas pu terminer la validation. Iran git reset, a rajouté les fichiers modifiés et réessayé pour obtenir ceci:

% 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 révèle ce qui suit:

% 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

Je remarque que les messages se plaignent d'objets différents.

J'ai cherché SO et le Web et essayé quelques choses différentes mais en vain.

  • Je n'ai pas de copie de sauvegarde récente.
  • Cloner le référentiel dans un autre répertoire n'aide pas. le nouveau référentiel présente exactement les mêmes problèmes.
  • git stash donne le même message que git commit. Toutes les autres commandes git semblent fonctionner normalement.

Comment puis-je savoir ce qui ne va pas et le réparer?

Edit:git log sortie comme suggéré (seulement les premières lignes):

% 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

C'est un petit projet personnel. D'habitude, je travaille uniquement dans (maître) mais je faisais une expérience à l'époque (new_tokenize). 253b086 était la dernière validation réussie avant la panne de courant.

60
trentcl

Il semble que git a créé des fichiers dans .git/objects pour le nouveau commit, mais n'y a pas réussi à écrire. Je l'ai résolu en les supprimant un à un et en relançant git fsck --full pour trouver le suivant. J'ai commencé avec celui initialement signalé par 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

Etc. J'ai supprimé cinq objets avant git fsck est venu propre, correspondant (comme je suppose) aux cinq fichiers du commit que j'essayais de créer. Je suppose que l'historique des fichiers n'a pas du tout été corrompu.

Incidemment, j'ai pensé à une autre méthode qui semble également fonctionner. git clone copie les mauvais objets, mais git Push ne fait pas. Après la sauvegarde, j'ai créé un nouveau référentiel vide (--bare, car sinon, vous ne pouvez pas utiliser la fonction Push to master), puis j'ai décompressé mes modifications et inséré les deux branches dans le nouveau référentiel. Ensuite, il suffisait de vérifier à nouveau et de restaurer les dernières modifications apportées par mes sauvegardes.

Vous êtes toujours intéressé si quelqu'un veut faire la lumière sur le mécanisme d'échec ici.

65
trentcl

Réponse simple à cette question pour les personnes confrontées à ce problème: la commande git clone est la solution. Si vous avez un référentiel distant, clonez-le dans le dossier local (après avoir supprimé le référentiel local corrompu), au cas où vous n’auriez pas de référentiel distant, puis essayez de le faire. Poussez le repo corrompu vers github puis clonez-le à partir de là. Je pense que les objets corrompus ne seront pas poussés et que cela résoudra le problème.

8
TooCooL

Comme décrit dans cette réponse j'ai exécuté:

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

Ce qui a enlevé tous mes blobs pendantes et mes commits, ainsi que les objets de base de données corrompus.

C'était beaucoup plus rapide que de les retrouver un par un!

6
BitBot