Essayez d'abord les commandes suivantes (réexécutez si nécessaire):
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
Et puis vous avez encore des problèmes, essayez de:
supprimer tous les objets corrompus, par exemple
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt
$ rm -v .git/objects/06/91c5...51e5
supprimer tous les objets vides, par ex.
error: object file .git/objects/06/91c5...51e5 is empty
$ find .git/objects/ -size 0 -exec rm -vf "{}" \;
vérifier un message "lien rompu" en:
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
Cela vous indiquera de quel fichier le blob corrompu provient!
pour récupérer le fichier, vous pourriez être vraiment chanceux, et c'est peut-être la version que vous avez déjà extraite dans votre arbre de travail:
git hash-object -w my-magic-file
encore une fois, et s'il sort le SHA1 manquant (4b945 ..) vous avez maintenant terminé!
en supposant que c'était une ancienne version qui était cassée, le moyen le plus simple de le faire est de faire:
git log --raw --all --full-history -- subdirectory/my-magic-file
et cela vous montrera tout le journal de ce fichier (veuillez vous rendre compte que l'arborescence que vous aviez n'est peut-être pas l'arborescence de niveau supérieur, vous devez donc déterminer vous-même dans quel sous-répertoire il se trouvait), alors vous pouvez maintenant recréer le objet manquant avec objet de hachage à nouveau.
pour obtenir une liste de toutes les références avec des commits, des arbres ou des blobs manquants:
$ git for-each-ref --format='%(refname)' | while read ref; do git rev-list --objects $ref >/dev/null || echo "in $ref"; done
Il peut ne pas être possible de supprimer certaines de ces références en utilisant les commandes branch -d ou tag -d normales, car elles mourront si git remarque la corruption. Utilisez donc la commande de plomberie git update-ref -d $ ref à la place. Notez que dans le cas de branches locales, cette commande peut laisser la configuration de branche périmée dans .git / config. Il peut être supprimé manuellement (recherchez la section [branche "$ ref"]).
Une fois que toutes les références sont propres, il peut encore y avoir des commits interrompus dans le reflog. Vous pouvez effacer tous les reflogs en utilisant git reflog expire --expire = now --all. Si vous ne voulez pas perdre tous vos reflogs, vous pouvez rechercher les refs individuels pour les reflogs cassés:
$ (echo HEAD; git for-each-ref --format='%(refname)') | while read ref; do git rev-list -g --objects $ref >/dev/null || echo "in $ref"; done
(Notez l'option -g ajoutée à git rev-list.) Ensuite, utilisez git reflog expire --expire = now $ ref sur chacun d'entre eux. Lorsque toutes les références et reflogs cassés ont disparu, exécutez git fsck --full afin de vérifier que le référentiel est propre. Les objets pendantes sont ok.
Vous trouverez ci-dessous une utilisation avancée des commandes qui peuvent potentiellement entraîner la perte de vos données dans votre référentiel git si elles ne sont pas utilisées à bon escient, alors faites une sauvegarde avant de causer accidentellement d'autres dommages à votre git. Essayez à vos risques et périls si vous savez ce que vous faites.
Pour extraire la branche actuelle au-dessus de la branche amont après l'extraction:
$ git pull --rebase
Vous pouvez également essayer de retirer une nouvelle branche et de supprimer l'ancienne:
$ git checkout -b new_master origin/master
Pour trouver l'objet corrompu dans git à supprimer, essayez la commande suivante:
while [ true ]; do f=`git fsck --full 2>&1|awk '{print $3}'|sed -r 's/(^..)(.*)/objects\/\1\/\2/'`; if [ ! -f "$f" ]; then break; fi; echo delete $f; rm -f "$f"; done
Pour OSX, utilisez à la sed -E
place de sed -r
.
Une autre idée est de décompresser tous les objets des fichiers de pack pour régénérer tous les objets dans .git / objects, alors essayez d'exécuter les commandes suivantes dans votre référentiel:
$ cp -fr .git/objects/pack .git/objects/pack.bak
$ for i in .git/objects/pack.bak/*.pack; do git unpack-objects -r < $i; done
$ rm -frv .git/objects/pack.bak
Si ci-dessus ne vous aide pas, vous pouvez essayer de rsync ou de copier les objets git d'un autre dépôt, par exemple
$ rsync -varu git_server:/path/to/git/.git local_git_repo/
$ rsync -varu /local/path/to/other-working/git/.git local_git_repo/
$ cp -frv ../other_repo/.git/objects .git/objects
Pour réparer la branche cassée lors de la tentative de paiement, procédez comme suit:
$ git checkout -f master
fatal: unable to read tree 5ace24d474a9535ddd5e6a6c6a1ef480aecf2625
Essayez de le supprimer et de procéder à nouveau au paiement en amont:
$ git branch -D master
$ git checkout -b master github/master
Dans le cas où git vous mettrait dans l'état détaché, vérifiez le master
et fusionnez-y la branche détachée.
Une autre idée est de rebaser le maître existant de manière récursive:
$ git reset HEAD --hard
$ git rebase -s recursive -X theirs origin/master
Voir également:
.git
dossier bien sûr) dans le référentiel fraîchement cloné ... et ensuite faitgit status
dans le nouveau dépôt ... git détecte correctement toutes les modifications affectées à mes fichiers et je peux recommencer mon travail.