web-dev-qa-db-fra.com

Réparer le référentiel Git corrompu

Mon référentiel Git a été corrompu après quelques redémarrages durs en raison de problèmes d'alimentation et maintenant je ne peux pas le réparer (j'étais en train de mettre en scène certains fichiers lors de la dernière panne de courant):

$ git status
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git fsck
fatal: failed to read object 24377c609184c192f3f3c1733bac7115c1080758: Invalid argument
$ git branch -a
(...works, lists branches...)
$ git checkout someotherbranch
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git log
fatal: failed to read object 3d18855708b0f127d40c13c679559d7679228b69: Invalid argument
$ git log someotherbranch
(...works, shows commits...)

Donc, comme vous pouvez le voir, ma branche actuelle est plutôt foutue, et je ne semble pas pouvoir y remédier. Que puis-je essayer de réparer cela?

40
Unknown

Ma solution pour une situation similaire a été de remplacer un hachage de l'objet endommagé dans .git/refs/heads/my-working-branch avec un hachage de la validation précédente (qui se trouve dans .git/logs/HEAD).

35
Nash Bridges

Cela m'est juste arrivé. Je reclone le référentiel dans un nouveau dossier et je déplace mes dernières modifications manuellement. Low tech, mais ça marche à chaque fois. J'espère que vous vous souviendrez de vos derniers changements.

16
nbushnell

Pour moi, j'avais activé TRIM dans OS X avec un SSD non Apple (ce qui n'est pas recommandé) et j'ai apparemment provoqué diverses corruptions sur mon disque de démarrage. Le commit corrompu était donc profondément dans l'histoire.

Je ne me soucie pas trop de réparer mon référentiel, sauf que j'ai quelques branches locales trop expérimentales pour prendre la peine de pousser vers le référentiel distant, et je voudrais récupérer le travail dans ces branches.

Théoriquement, puisqu'il s'agit d'un référentiel local, je pense que Git devrait être capable de récupérer/réparer lui-même en utilisant Origin. Pourquoi n'est-ce pas possible?

En tout cas, je suis tombé sur cette stratégie cool pour pousser une branche vers un autre référentiel Git local . Malheureusement, le clonage du référentiel dans ../repo_copy puis l'utiliser en tant que télécommande locale a provoqué l'erreur suivante:

! git Push --force local_remote HEAD
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument
error: failed to Push some refs to '/Users/steve/Dev/repo_copy'

J'ai donc commencé à la place avec un référentiel vide, puis y pousser des branches a bien fonctionné. Donc, pour toute branche locale dont j'avais git log ne s'est pas terminé par:

....
    Fixing cukes
fatal: failed to read object e0a9dffddeeca96dbaa275636f8e8f5d4866e0ed: Invalid argument

Je voudrais simplement le vérifier et ensuite faire git Push --force local_remote HEAD. La dernière chose que j'ai faite a été:

! cd ~/Dev/repo_copy
! git remote add Origin [email protected]:sdhull/my_repo.git  # real remote

Ensuite, je suis allé à git config -e et mis en place ma branche principale et était de nouveau opérationnel sans rien perdre!

9
steve

Essayez de faire une sauvegarde du référentiel puis d'exécuter git reset --hard HEAD@{1} pour revenir à la précédente HEAD et voir si cela fonctionne. Il peut s'agir uniquement du HEAD actuel qui est corrompu.

(Vous devriez également exécuter fsck sur votre disque si vous ne l'avez pas déjà fait.)

7
Michael Mior

La solution la plus simple pour moi: vous pourriez git clone dans un nouveau dossier, puis remplacez le nouveau dossier_/git .git par l'ancien dossier (le dossier cassé). Ça marche bien pour moi!

git clone ...(remote) new_folder
mv old_folder/.git  old_folder/.git_old
cp -R new_folder/.git  old_folder/
3
sanji_mika

J'ai pu récupérer mon référentiel à partir de:

zsh(broken)% git log master
error: object file .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395 is empty
error: object file .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395 is empty
fatal: loose object 7fcab8648a989d9bb3f5246e6be7220395493395 (stored in .git/objects/7f/cab8648a989d9bb3f5246e6be7220395493395) is corrupt
zsh(broken)% cat .git/refs/heads/master
7fcab8648a989d9bb3f5246e6be7220395493395
e311726c4eb970f4d4f504ad86248d322855018f da9c14d03e4849394087b61ff6272399937f7cce Nikolay Orliuk <[email protected]> 1379583764 +0300    commit: plan: timings

En réinitialisant master pour la validation précédente da9c14d03e4849394087b61ff6272399937f7cce comme l'a expliqué @Nash Bridges:

zsh(broken)% echo da9c14d03e4849394087b61ff6272399937f7cce > .git/refs/heads/master
zsh(broken)% git log --oneline -1 master
da9c14d plan: timings
zsh(broken)% git fsck
Checking object directories: 100% (256/256), done.
error: object file .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5 is empty
error: object file .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5 is empty
fatal: loose object 0eace931fdc851da254e9522596d1517d0ed51c5 (stored in .git/objects/0e/ace931fdc851da254e9522596d1517d0ed51c5) is corrupt

Création d'un nouveau référentiel vide, récupérant master de cassé:

zsh(broken)% mkdir ../recover && cd ../recover && git init
Initialized empty Git repository in /home/nikolay/talks/y/recover/.git/
zsh(recover)% git fetch ../broken master
remote: Counting objects: 44, done.
remote: Compressing objects: 100% (44/44), done.
remote: Total 44 (delta 20), reused 0 (delta 0)
Unpacking objects: 100% (44/44), done.
From ../broken
 * branch            master     -> FETCH_HEAD
zsh(recover)% git reset --hard FETCH_HEAD
HEAD is now at da9c14d plan: timings
zsh% git fsck
Checking object directories: 100% (256/256), done.

Pour restaurer les modifications en cours vers master:

zsh(recover)% rm -rf * && cp -a ../broken/* ./
zsh(recover)% git add -u && git commit -m 'prepare for publishing'
2
ony

Une autre alternative qui a fonctionné pour moi a été de réinitialiser la tête et l'index Git à leur état précédent en utilisant:

git reset --keep

J'ai également essayé les commandes suivantes, mais elles n'ont pas fonctionné pour moi, mais elles pourraient le faire pour vous:

git reset --mixed
git fsck --full
git gc --auto
git Prune --expire now
git reflog --all
2
gaborous

J'ai eu le même problème et j'ai fait les étapes suivantes en utilisant git-repair

  • cp myrepo myrepo.bak
  • cd myrepo
  • git repair --force (essayez d'abord sans force)

Une fois cette opération réussie, l'arborescence a été redéfinie sur le dernier commit de travail.

Ensuite, j'ai fait meld myrepo myrepo.bak pour appliquer les modifications de l'arborescence de travail du référentiel corrompu au référentiel fixe.

1
student

J'ai suivi les instructions trouvées dans Récupération à partir d'un référentiel Git corromp:

$ cd /tmp/
$ git clone good-Host:/path/to/good-repo
$ cd /home/user/broken-repo
$ echo /tmp/good-repo/.git/objects/ > .git/objects/info/alternates
$ git repack -a -d
$ rm -rf /tmp/good-repo

Ça a marché pour moi.

1
MrJ