web-dev-qa-db-fra.com

Git: "Objet détaché corrompu"

Chaque fois que je tire de ma télécommande, j'obtiens l'erreur suivante concernant la compression. Quand je lance la compression manuelle, je reçois le même:

$ git gc
error: Could not read 3813783126d41a3200b35b6681357c213352ab31
fatal: bad tree object 3813783126d41a3200b35b6681357c213352ab31
error: failed to run repack

Est-ce que quelqu'un sait, que faire à ce sujet?

Je reçois ceci de la lime à chat: 

$ git cat-file -t 3813783126d41a3200b35b6681357c213352ab31
error: unable to find 3813783126d41a3200b35b6681357c213352ab31
fatal: git cat-file 3813783126d41a3200b35b6681357c213352ab31: bad file

Et de git fsck, j’obtiens ceci (je ne sais pas si c’est vraiment lié):

$ git fsck
error: inflate: data stream error (invalid distance too far back)
error: corrupt loose object '45ba4ceb93bc812ef20a6630bb27e9e0b33a012a'
fatal: loose object 45ba4ceb93bc812ef20a6630bb27e9e0b33a012a (stored in .git/objects/45/ba4ceb93bc812ef20a6630bb27e9e0b33a012a) is corrupted

Quelqu'un peut-il m'aider à déchiffrer ceci?

260
asgerhallas

On dirait que vous avez un objet d'arbre corrompu. Vous aurez besoin d'obtenir cet objet de quelqu'un d'autre. Espérons qu'ils auront une version non corrompue.

Vous pouvez en fait la reconstruire si vous ne pouvez pas trouver une version valide de quelqu'un d'autre en devinant quels fichiers devraient être là. Vous voudrez peut-être voir si les dates et les heures des objets correspondent. Celles-ci pourraient être les blobs liés. Vous pouvez en déduire la structure de l'objet tree.

Jetez un coup d’œil à Screencasts Git de Scott Chacon concernant les internes de Git. Cela vous montrera comment git fonctionne sous le capot et comment s'y prendre pour faire ce travail de détective si vous êtes vraiment bloqué et ne pouvez pas obtenir cet objet de quelqu'un d'autre.

54
Adam Dymitruk

J'ai eu le même problème (je ne sais pas pourquoi).

Ce correctif nécessite l'accès à une copie à distance non corrompue du référentiel et préservera votre copie de travail localement.

Mais il y a des inconvénients:

  • Vous perdrez l'enregistrement de tous les commits qui n'ont pas été poussés et vous devrez les réengager.
  • Vous allez perdre toutes les caches.

Le correctif

Exécutez ces commandes depuis le répertoire parent au-dessus de votre référentiel (remplacez 'foo' par le nom de votre dossier de projet):

  1. Créez une sauvegarde du répertoire corrompu:
    cp -R foo foo-backup
  2. Créez un nouveau clone du référentiel distant dans un nouveau répertoire:
    git clone [email protected]:foo foo-newclone
  3. Supprimez le sous-répertoire .git corrompu:
    rm -rf foo/.git
  4. Déplacez le sous-répertoire .git nouvellement cloné dans foo:
    mv foo-newclone/.git foo
  5. Supprimez le reste du nouveau clone temporaire:
    rm -rf foo-newclone

Sous Windows, vous devrez utiliser:

  • copy au lieu de cp -R 
  • rmdir /S au lieu de rm -rf
  • move au lieu de mv

Foo a maintenant son sous-répertoire .git original, mais toutes les modifications locales sont toujours présentes. git status, commit, pull, Push, etc. fonctionnent à nouveau comme il se doit.

296
cubic lettuce

Votre meilleur pari est probablement de simplement cloner à nouveau à partir du dépôt distant (par exemple, Github ou autre). Malheureusement, vous perdrez toutes les modifications non stockées et validées, mais votre copie de travail doit rester intacte.

Commencez par faire une copie de sauvegarde de vos fichiers locaux. Ensuite, faites ceci à partir de la racine de votre arbre de travail:

rm -fr .git
git init
git remote add Origin [your-git-remote-url]
git fetch
git reset --mixed Origin/master
git branch --set-upstream-to=Origin/master master  

Puis validez tous les fichiers modifiés si nécessaire.

188
user1055643

Travailler sur une machine virtuelle, dans mon ordinateur portable, la batterie est morte, j'ai eu cette erreur;

error: le fichier objet .git/objects/ce/theRef est vide error: object Le fichier .git/objects/ce/theRef est vide. Fatal: objet en vrac theRef (stocké dans .git/objects/ce/theRef) est corrompu

J'ai réussi à faire fonctionner le référentiel à nouveau avec seulement 2 commandes et sans perdre mon travail (fichiers modifiés/modifications non validées)

find .git/objects/ -size 0 -exec rm -f {} \;
git fetch Origin

Après cela, j’ai exécuté un git status, le repo était bon et il y avait mes modifications (en attente de validation, faites-le maintenant ..).

version git 1.9.1

N'oubliez pas de sauvegarder toutes les modifications dont vous vous souvenez, au cas où cette solution ne fonctionnerait pas et qu'une approche plus radicale serait nécessaire.

92
Felipe Pereira

Mon ordinateur est tombé en panne pendant que j'écrivais un message de validation. Après le redémarrage, l’arborescence de travail était telle que je l’avais laissée et j’ai été en mesure de valider mes modifications.

Cependant, quand j’ai essayé d’exécuter git status j’ai eu

error: object file .git/objects/xx/12345 is empty
fatal: loose object xx12345 (stored in .git/objects/xx/12345 is corrupt

Contrairement à la plupart des autres réponses, je n'essayais pas de récupérer des données. J'avais juste besoin que Git cesse de se plaindre du fichier objet vide.

Vue d'ensemble

Le "fichier objet" est la représentation hachée de git d'un fichier réel qui vous tient à cœur. Git pense qu'il devrait avoir une version hachée de some/file.whatever stockée dans .git/object/xx/12345, et réparer l'erreur s'est avéré être une simple question de savoir quel fichier "l'objet volant" était supposé représenter.

Détails

Les options possibles semblaient être

  1. Supprimer le fichier vide
  2. Mettre le fichier dans un état acceptable pour Git

Approche 1: Supprimer le fichier objet

La première chose que j'ai essayée était juste de déplacer le fichier d'objet

mv .git/objects/xx/12345 ..

Cela n'a pas fonctionné - git a commencé à se plaindre d'un lien brisé. A l'approche 2.

Approche 2: Corrige le fichier

Linus Torvalds a rédigé une excellente description de comment récupérer un fichier objet qui a résolu le problème pour moi. Les étapes clés sont résumées ici.

$> # Find out which file the blob object refers to
$> git fsck
broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
           to    blob xx12345
missing blob xx12345

$> git ls-tree 2d926
...
10064 blob xx12345  your_file.whatever

Cela vous indique quel fichier l'objet vide est supposé être un hachage. Maintenant, vous pouvez le réparer.

$> git hash-object -w path/to/your_file.whatever

Après cela, j’ai vérifié .git/objects/xx/12345, il n’était plus vide et git a cessé de se plaindre.

37
declan

Essayer

git stash

Cela a fonctionné pour moi. Il cache tout ce que vous n'avez pas commis et qui résout le problème.

12
Arthur

A ramasse-miettes corrige mon problème:

git gc --aggressive --Prune=now

Cela prend un certain temps, mais chaque objet desserré et/ou index corrompu était corrigé.

4
Jago

Je viens de faire l'expérience de ceci - ma machine s'est écrasée lors de l'écriture dans le dépôt Git, et elle est devenue corrompue. Je l'ai corrigé comme suit.

J'ai commencé par regarder le nombre de commits que je n'avais pas poussés dans le dépôt distant, ainsi:

gitk &

Si vous n'utilisez pas cet outil, il est très pratique - disponible sur tous les systèmes d'exploitation, à ma connaissance. Cela indiquait qu'il manquait deux commits sur ma télécommande. J'ai donc cliqué sur l'étiquette indiquant la dernière validation à distance (généralement ce sera /remotes/Origin/master) pour obtenir le hachage (le hachage est long de 40 caractères, mais par souci de brièveté, j'utilise 10 ici - cela fonctionne de toute façon).

C'est ici:

14c0fcc9b3

Je clique ensuite sur le commit suivant (c'est-à-dire le premier que la télécommande n'a pas) et récupère le hash:

04d44c3298

J'utilise ensuite les deux pour créer un correctif pour ce commit:

git diff 14c0fcc9b3 04d44c3298 > 1.patch

J'ai ensuite fait de même avec l'autre commit manquant, c'est-à-dire que j'ai utilisé le hachage du commit avant et le hachage du commit lui-même:

git diff 04d44c3298 fc1d4b0df7 > 2.patch

J'ai ensuite déplacé vers un nouveau répertoire, cloné le repo de la télécommande:

git clone [email protected]:username/repo.git

J'ai ensuite déplacé les fichiers de correctif dans le nouveau dossier, puis les ai appliqués et les ai validés avec leurs messages de validation exacts (ceux-ci peuvent être collés à partir de git log ou de la fenêtre gitk):

patch -p1 < 1.patch
git commit

patch -p1 < 2.patch
git commit

Cela a restauré les choses pour moi (et notez qu'il existe probablement un moyen plus rapide de le faire pour un grand nombre de commits). Cependant, je souhaitais savoir si l’arbre du référentiel corrompu pouvait être réparé et la réponse à cette question est possible. Avec un repo réparé disponible comme ci-dessus, exécutez cette commande dans le dossier cassé:

git fsck 

Vous obtiendrez quelque chose comme ceci:

error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d

Pour faire la réparation, je le ferais dans le dossier endommagé:

rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d

c'est-à-dire supprimer le fichier corrompu et le remplacer par un bon. Vous devrez peut-être faire cela plusieurs fois. Enfin, vous pourrez exécuter fsck sans erreur. Vous aurez probablement des lignes "suspendre suspendu" et "balançant suspendu" dans le rapport. Celles-ci sont une conséquence de vos modifications de bases et modifications dans ce dossier, et sont OK. Le ramasse-miettes les enlèvera en temps voulu.

Ainsi (du moins dans mon cas) un arbre corrompu ne signifie pas que les commits non envoyés sont perdus.

4
halfer

En réponse de @ user1055643, il manque la dernière étape:

$ rm -fr .git
$ git init
$ git remote add Origin your-git-remote-url
$ git fetch
$ git reset --hard Origin/master
$ git branch --set-upstream-to=Origin/master master  
3

Je devenais une erreur d'objet détaché corrompu aussi.

./objects/x/x

J'ai réussi à le réparer en allant dans le répertoire de l'objet corrompu. J'ai vu que les utilisateurs assignés à cet objet étaient pas mon utilisateur git. Je ne sais pas comment c'est arrivé, mais j'ai exécuté un chown git:git sur ce fichier, puis cela a fonctionné à nouveau.

Cela peut constituer une solution potentielle aux problèmes de certaines personnes, mais pas nécessairement à toutes.

3
Dez

J'ai eu cette erreur après que ma machine (Windows) ait décidé de se redémarrer.

2
Dean Rather

J'ai suivi beaucoup d'autres étapes ici; La description par Linus de la manière de regarder l'arbre/les objets git et de trouver ce qui manque était particulièrement utile. git-git récupère un blob corrompu

Mais au final, pour moi, j'avais des objets d'arbre lâchés/corrompus causés par une défaillance partielle du disque, et les objets d'arbre ne sont pas aussi faciles à récupérer/non couverts par ce document.

En fin de compte, j'ai déplacé le objects/<ha>/<hash> en conflit et utilisé git unpack-objects avec un fichier de pack d'un clone raisonnablement à jour. Il a été capable de restaurer les objets d'arborescence manquants.

Il me reste encore beaucoup de blobs en suspens, ce qui peut être un effet secondaire du déballage de documents précédemment archivés et traités dans d’autres questions ici

2
davenpcj

J'ai résolu de cette manière: J'ai décidé de simplement copier le fichier objet non corrompu du clone de la sauvegarde dans mon référentiel d'origine. Cela a fonctionné aussi bien. (Au fait: si vous ne trouvez pas l'objet dans .git/objects/par son nom, il a probablement été emballé pour économiser de l'espace.)

1
mcginn

Pour moi, cela est dû à une panne de courant lors de l'exécution d'un git Push.

Les messages ressemblaient à ceci:

$ git status
error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
error: object file .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74 is empty
fatal: loose object c238824eb3fb602edc2c49fccb535f9e53951c74 (stored in .git/objects/c2/38824eb3fb602edc2c49fccb535f9e53951c74) is corrupt

J'ai essayé des choses comme git fsck mais cela n'a pas aidé… .. Depuis l'incident est survenu pendant un git Push, cela s'est évidemment produit lors de la réécriture côté client après la mise à jour du serveur. Je regardai autour de moi et pensai que c2388 était dans mon cas un objet commit, car il était référencé par des entrées dans .git/refs. Je savais donc que je pourrais trouver c2388 quand je regarderais l'historique (via une interface Web ou un deuxième clone).

Sur le deuxième clone, j'ai fait un git log -n 2 c2388 pour identifier le prédécesseur de c2388. Ensuite, j'ai modifié manuellement .git/refs/heads/master et .git/refs/remotes/Origin/master pour qu'il devienne le prédécesseur de c2388 au lieu de c2388. Ensuite, je pouvais effectuer un git fetch. Le git fetch a échoué à quelques reprises pour des conflits d'objets vides. J'ai supprimé chacun de ces objets vides jusqu'à ce que git fetch réussisse. Cela a guéri le référentiel.

1
Christian Hujer

Lancer git stash; git stash pop corrige mon problème

1
Simonluca Landi

exécuter simplement un git Prune a résolu ce problème pour moi

0
Tyler Gauch

Nous venons d'avoir l'affaire ici. Il est arrivé que le problème soit que la propriété du fichier corrompu soit la racine au lieu de notre utilisateur normal. Cela est dû à une validation effectuée sur le serveur après que quelqu'un a effectué un "Sudo su -".

Commencez par identifier votre fichier corrompu avec:

$> git fsck --full

Vous devriez recevoir une réponse comme celle-ci:

fatal: loose object 11b25a9d10b4144711bf616590e171a76a35c1f9 (stored in .git/objects/11/b25a9d10b4144711bf616590e171a76a35c1f9) is corrupt

Allez dans le dossier où se trouve le fichier corrompu et faites un:

$> ls -la

Vérifiez la propriété du fichier corrompu. Si c'est différent, retournez à la racine de votre dépôt et faites un:

$> Sudo chown -R YOURCORRECTUSER:www-data .git/

J'espère que ça aide!

0
Thomas Lobjoie

Lorsque j'ai eu ce problème, j'ai sauvegardé mes dernières modifications (car je savais ce que j'avais changé), puis supprimé ce fichier dont il se plaignait dans .git/location. Ensuite, j'ai tiré un git. Faites attention cependant, cela pourrait ne pas fonctionner pour vous.

0
gareth

Je viens d'avoir un problème comme celui-ci. Mon problème particulier a été causé par un plantage du système qui a corrompu le dernier commit (et donc aussi la branche master). Je n'avais pas insisté et je voulais ré-engager ce jeu. Dans mon cas particulier, j'ai été capable de gérer cela comme ceci:

  1. Faites une sauvegarde de .git/: rsync -a .git/ git-bak/
  2. Vérifiez .git/logs/HEAD et recherchez la dernière ligne avec un ID de validation valide. Pour moi, c'était le deuxième commit le plus récent. C’était bien, car j’avais toujours les versions du répertoire de travail du fichier, et donc toutes les versions que je voulais.
  3. Créez une branche à ce commit: git branch temp <commit-id>
  4. refaites la validation avec les fichiers du répertoire de travail.
  5. git reset master temp pour déplacer la branche principale vers le nouveau commit que vous avez effectué à l'étape 2.
  6. git checkout master et vérifiez que tout se passe bien avec git log.
  7. git branch -d temp.
  8. git fsck --full, et il devrait maintenant être sûr de supprimer tous les objets corrompus trouvés par fsck. 
  9. Si tout semble bon, essayez de pousser. Si cela fonctionne, 

Cela a fonctionné pour moi. Je soupçonne qu’il s’agit d’un scénario assez courant, car le dernier commit est le plus susceptible d’être corrompu, mais si vous en perdez un en arrière, vous pouvez probablement utiliser une méthode comme celle-ci, en utilisant avec précaution git cherrypick reflog dans .git/logs/HEAD.

0
naught101

J'ai eu ce même problème dans mon repo Git à distance nue. Après beaucoup de dépannage, je me suis aperçu qu'un de mes collègues avait fait un commit dans lequel certains fichiers de .git/objects avaient des permissions de 440 (r - r -----) au lieu de 444 -). Après avoir demandé au collègue de modifier les autorisations avec "objets chmod 444 -R" dans le dépôt à nu Git, le problème a été résolu.

0
konyak