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?
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
).
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.
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!
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.)
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/
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'
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
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.
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.