Référentiel Git corrompu (vérification d’en-tête incorrecte, object détaché corrompu)

J’ai subi une panne de courant hier soir lors de la rédaction d’un message de validation. Lorsque j’ai démarré la machine, je ne pouvais pas terminer la validation. J’ai lancé git reset , rajouté les fichiers modifiés et essayé à nouveau, et j’ai obtenu 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 de différents objects.

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

  • Je n’ai pas de copie de sauvegarde récente.
  • Le clonage du 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 output comme suggéré (juste 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 

Ceci est un petit projet personnel; Je travaille habituellement en (master) mais je faisais une expérience à l’époque (new_tokenize). 253b086 était la dernière validation réussie avant la panne de courant.

    Il semble que git ait créé des fichiers dans les objects .git / pour le nouvel commit, mais n’a pas réussi à leur écrire. Je l’ai résolu en les supprimant un par 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 objects avant que git fsck ne soit 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 été corrompu du tout.

    D’ailleurs, j’ai pensé à une autre méthode qui semble fonctionner aussi bien. git clone copie les objects défectueux, mais git push ne git push fait pas. Après avoir sauvegardé, j’ai créé un nouveau référentiel vide (–bare, car sinon vous ne pouvez pas pousser à maîsortingser), puis désarchivez mes modifications et poussez les deux twigs dans le nouveau référentiel. Ensuite, il suffisait de vérifier à nouveau et de restaurer les dernières modifications de mes sauvegardes.

    Toujours intéressé si quelqu’un se soucie de faire la lumière sur le mécanisme de défaillance ici.

    Une réponse simple à cette question pour quiconque est confronté à ce problème: la commande git clone est le correctif, si vous avez un repo distant, clonez-le dans le dossier local (après avoir supprimé le repo local corrompu). poussez le repo corrompu sur github puis clonez-le à partir de là, je pense que les objects corrompus ne seront pas poussés et cela résoudra le problème

    Comme décrit dans cette réponse, j’ai couru:

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

    Qui a enlevé tous mes blobs pendants et tous les commits, ainsi que les objects db corrompus.

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