Je viens de vivre cela - ma machine s'est écrasée lors de l'écriture dans le référentiel Git, et elle est devenue corrompue. Je l'ai corrigé comme suit.
J'ai commencé par regarder combien de commits je n'avais pas poussés vers le référentiel 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 a indiqué que ma télécommande manquait deux commits. 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 fait 40 caractères, mais pour plus de concision, j'utilise 10 ici - cela fonctionne généralement 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 j'y trouve le hachage:
04d44c3298
J'utilise ensuite les deux pour créer un patch 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 hash du commit lui-même:
git diff 04d44c3298 fc1d4b0df7 > 2.patch
J'ai ensuite déménagé dans un nouveau répertoire, cloné le référentiel depuis la télécommande:
git clone git@github.com:username/repo.git
J'ai ensuite déplacé les fichiers de correctifs dans le nouveau dossier, et les ai appliqués et validés avec leurs messages de validation exacts (ceux-ci peuvent être collés depuis git log
ou dans la gitk
fenêtre):
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, j'étais impatient de voir si l'arbre du dépôt corrompu pouvait être réparé, et la réponse est oui. Avec un référentiel 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 cassé:
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 le faire plusieurs fois. Enfin, il y aura un point où vous pourrez exécuter fsck
sans erreurs. Vous aurez probablement des lignes "commit pendant" et "blob pendantes" dans le rapport, elles sont la conséquence de vos rebases et modifications dans ce dossier, et elles sont OK. Le garbage collector les supprimera en temps voulu.
Ainsi (au moins dans mon cas) un arbre corrompu ne signifie pas que les commits non poussés sont perdus.