147 votes

Comment réparer un dépôt Git corrompu ?

J'ai essayé de cloner mon référentiel que je conserve dans ma base de données. Ubuntu One sur une nouvelle machine, et j'ai obtenu ceci :

cd ~/source/personal
git clone ~/Ubuntu\ One\ Side\ Work/projects.git/

Cloning into 'projects'...
done.
fatal: unable to read tree 29a422c19251aeaeb907175e9b3219a9bed6c616

J'ai donc essayé de regarder les nombreuses autres questions de ce type qui ont été posées ici et la plupart d'entre elles disent de courir git fsck --full et ensuite j'obtiens ceci quand j'essaie ça.

cd ~/Ubuntu\ One\ Side\ Work/projects.git
git fsck --full

Checking object directories: 100% (256/256), done.
Checking objects: 100% (447/447), done.
broken link from  commit 235ae1f48701d577d71ebd430344a159e5ba4881
              to  commit 984c11abfc9c2839b386f29c574d9e03383fa589
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    blob 25a742dff0a403b2b3884f2ffddf63eb45721fac
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    blob dd4e97e22e159a585b20e21028f964827d5afa4e
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    tree 29a422c19251aeaeb907175e9b3219a9bed6c616
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    tree 8084e8e04d510cc28321f30a9646477cc50c235c
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob a0daa0c1567b55d8de2b4d7a3bc010f58c047eab
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob e9052d35bfb6d30065b206fc43f4200a04d5281b
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob 1a3a5e4dd2502ac121c22f743c4250e254a94eeb
broken link from    tree 4aa336dc1a5838e8918e03b85580069d83f4ad09
              to    tree 8cc55ec952dc192a233e062201d1e7e873ac3db0
broken link from    tree e5674a91a53e15575a1f3bf5786bc5cc719fb483
              to    blob 4a994e1e7bb7ce28dcec98bad48b9a891d7dec51
broken link from    tree e5674a91a53e15575a1f3bf5786bc5cc719fb483
              to    blob ac033bf9dc846101320c96a5ce8aceb8c96ec098
broken link from    tree 252ab84542264e1589576b6ee51e7a31e580a0e2
              to    tree 2069041cd5950e529e2991d37b7290ec021d90d4
broken link from    tree 2d4964aa4d4f5d8c7228518ce72ef6a63f820c6d
              to    blob d83690e1b9a6bdd8a08754b38231799acefcb2ab
broken link from    tree c7192e82fc581bd6448bda1a25e8729bdac5f4ff
              to    blob 30d54d47ae82add1917ca173d42e58b396df580b
broken link from    tree 7c66306901fc71389623286936cef172d4ffe408
              to    blob bc7e05d705401273b1df4e939de0f540597c0931
broken link from    tree 0940f5fd227d4c84d6e6749d872db50a4522ae3a
              to    tree 923767594ac22023e824948d65622fe5b407d1a1
broken link from    tree 8eadcd2a971e8357d24f0d80f993d2963452209f
              to    blob 2598bde3dc8cb80ee49510b8159344004b88645f
broken link from    tree ffa302dd0d969172ef23caeefe856ab2f57a4e4d
              to    blob d6925fa431be1ac585bf9a481e98f75107a6e6fb
broken link from    tree 7045b8870a49ce30a2027537a96d73d162bda773
              to    blob 25688652dea26f61f576ca1b52b9d1a18fbfd01d
broken link from    tree 37e4705d34bd440ce681ae32ae9a180a13256d72
              to    tree 246f564d4cee53339b8a4244f3173b61caa518eb
missing blob d6925fa431be1ac585bf9a481e98f75107a6e6fb
missing blob ac033bf9dc846101320c96a5ce8aceb8c96ec098
missing tree 29a422c19251aeaeb907175e9b3219a9bed6c616
missing tree 8084e8e04d510cc28321f30a9646477cc50c235c
missing blob 30d54d47ae82add1917ca173d42e58b396df580b
missing tree 8cc55ec952dc192a233e062201d1e7e873ac3db0
missing blob e9052d35bfb6d30065b206fc43f4200a04d5281b
dangling tree 4b26e95db542c72ac4a22ec25abe38fb2de79752
missing blob d83690e1b9a6bdd8a08754b38231799acefcb2ab
missing blob 25a742dff0a403b2b3884f2ffddf63eb45721fac
missing tree 923767594ac22023e824948d65622fe5b407d1a1
missing blob 25688652dea26f61f576ca1b52b9d1a18fbfd01d
missing blob 2598bde3dc8cb80ee49510b8159344004b88645f
dangling tree 3a683869f1bb0c1634de75700c316b3b36570dbd
dangling blob 4098d30843380d798a811f1aa9a02994f0dbbb27
missing tree 2069041cd5950e529e2991d37b7290ec021d90d4
missing blob 4a994e1e7bb7ce28dcec98bad48b9a891d7dec51
missing blob 1a3a5e4dd2502ac121c22f743c4250e254a94eeb
missing blob a0daa0c1567b55d8de2b4d7a3bc010f58c047eab
dangling tree 6c7b5162aa7a303fa3fe8dc393c5da564e309521
missing commit 984c11abfc9c2839b386f29c574d9e03383fa589
missing blob bc7e05d705401273b1df4e939de0f540597c0931
missing blob dd4e97e22e159a585b20e21028f964827d5afa4e
missing tree 246f564d4cee53339b8a4244f3173b61caa518eb
dangling commit a01f5c1e5315dc837203d6dee00d3493be9c5db9

Ça a l'air vraiment mauvais. Quand je fais un git log | head Je reçois ceci

git log | head

error: Could not read 984c11abfc9c2839b386f29c574d9e03383fa589
fatal: Failed to traverse parents of commit 235ae1f48701d577d71ebd430344a159e5ba4881
commit 2fb0d2d0643b445440f01b164f11ee9ee71fca48
Author: christopher <christopher@christopher.christopher>
Date:   Wed Aug 7 15:51:42 2013 -0400

    finishing chapter 7

D'autres questions ici ont dit de regarder ./git/refs/heads/master . C'est un repo nu et refs/heads/ existe mais refs/heads/master ne le fait pas. HEAD dans le dépôt nu dit ref: refs/heads/master cependant.

packed-refs dit cependant ceci

# pack-refs with: peeled
2fb0d2d0643b445440f01b164f11ee9ee71fca48 refs/heads/master

D'autres questions encore ont suggéré de courir git reflog et aucun résultat ne s'affiche lorsque je l'exécute.

Donc je n'ai vraiment aucune idée de ce qu'il faut faire ici. Quelle stratégie adopter ? Est-il possible de réinitialiser la tête à ce dernier commit du 7 août ?

Faire un git log et en allant au bas de l'écran, la sortie montre ceci :

commit 996e03b949aea176238e3c7a8452700bbb987ac9
Author: christopher <christopher@christopher>
Date:   Wed Jul 3 23:00:44 2013 -0400

    many many changes
error: Could not read 984c11abfc9c2839b386f29c574d9e03383fa589
fatal: Failed to traverse parents of commit 235ae1f48701d577d71ebd430344a159e5ba4881

Cela semble empêcher l'élagage de Git de fonctionner.

0voto

certilremy Points 106

Un moyen rapide si vous avez un changement dans votre projet actuel et ne voulez pas le perdre, déplacez votre projet actuel quelque part, clonez le projet de GitHub à ce dossier et faites quelques changements et essayez de commiter à nouveau.

Ou simplement supprimer le référentiel et le cloner à nouveau. Cela a fonctionné pour moi.

0voto

Gesthemene Points 59

Je voulais ajouter ce commentaire sous La réponse géniale de Zoey Hewil ci-dessus, mais je n'ai pas actuellement assez de représentants pour le faire, donc je dois l'ajouter ici et donner le crédit pour son travail :P

Si vous utilisez Poshgit et se sentent exceptionnellement paresseux, vous pouvez utiliser ce qui suit pour extraire automatiquement votre URL de votre configuration Git et rendre un travail facile encore plus facile. Les avertissements habituels s'appliquent : vous devez tester cette méthode sur une copie ou sauvegarder votre dépôt local au cas où elle vous exploserait à la figure.

$config = get-content .git\config
$url = $config -match "    url = (?<content>.*)"
$url = $url.trim().Substring(6)
$url

move-item -v .git .git_old;
git init;
git remote add origin "$url";
git fetch;
git reset origin/master --mixed

0voto

Peter Horvath Points 2177

Si rien de ce qui précède ne fonctionne, voici un rapport selon lequel La modification de git avec des vérifications désactivées a très bien fonctionné pour moi. Je viens de réparer avec elle un repo "irrécupérable".

L'essentiel :

Les objets binaires git (dans .git/objects ) sont juste des blobs compressés par gzip, emballés ensemble dans un format de données binaires. Dans la plupart des cas, si ces fichiers sont endommagés, vous pourriez obtenir une récupération partielle très efficace - si git le supportait. Il y a plusieurs vérifications (principalement : le fichier objet ne peut pas être ouvert, ou la décompression du blob entraîne une erreur) ; il arrête le traitement avec une erreur fatale.

Cela nécessite un peu de connaissances en C, au moins au niveau où vous pouvez patcher et recompiler le git à partir des sources. Ce que vous devez modifier, c'est toujours la même chose : git arrête quelque part le traitement avec une erreur fatale, donc vous le commentez et le remplacez par un mock vide. Après cela, un /your/patched/git gc --aggressive --prune=now (repacker commun super-agressif) répare ce qui doit l'être. Par exemple, le patch ci-dessous permet de corriger un repo git où certains fichiers objets sont endommagés. Bien sûr, la réparation n'est que partielle : les fichiers des objets endommagés sont perdus, même rétroactivement.

C'est peut-être la raison pour laquelle le développement de git ne met pas en œuvre une amélioration aussi mineure, mais extrêmement utile. Je pense que la taille du patch nécessaire serait probablement inférieure à 100 lignes.

En développant l'idée, il est probable qu'un fork git puisse être créé, permettant de récupérer ces dépôts endommagés.

diff -urNw orig/sha1-file.c patched/sha1-file.c
--- orig/sha1-file.c   2021-03-08 21:36:01.000000000 +0100
+++ patched/sha1-file.c 2021-08-19 18:32:44.019115545 +0200
@@ -1285,8 +1285,16 @@
        else if (stream->avail_in)
                error(_("garbage at end of loose object '%s'"),
                      oid_to_hex(oid));
+
+  error("error ignored");
+
+  /*
        free(buf);
        return NULL;
+  */
+
+  status = Z_OK;
+  return buf;
 }

 /*
@@ -1656,7 +1664,7 @@
                    oid_to_hex(repl), oid_to_hex(oid));

        if (!stat_loose_object(r, repl, &st, &path))
-               die(_("loose object %s (stored in %s) is corrupt"),
+               error(_("loose object %s (stored in %s) is corrupt"),
                    oid_to_hex(repl), path);

        if ((p = has_packed_and_bad(r, repl->hash)) != NULL)
@@ -1664,7 +1672,9 @@
                    oid_to_hex(repl), p->pack_name);
        obj_read_unlock();

-       return NULL;
+  errno = 0;
+  error("error ignored");
+       return strdup("");
 }

 void *read_object_with_reference(struct repository *r,
@@ -2473,10 +2483,12 @@
        }
        git_inflate_end(stream);

+  /*
        if (status != Z_STREAM_END) {
                error(_("corrupt loose object '%s'"), oid_to_hex(expected_oid));
                return -1;
-       }
+       }*/
+
        if (stream->avail_in) {
                error(_("garbage at end of loose object '%s'"),
                      oid_to_hex(expected_oid));

0voto

git-repair ( sudo apt install git-repair ) avec quelques commandes supplémentaires a fonctionné pour moi :

  1. Créez une copie de sauvegarde de votre référentiel corrompu.

  2. Supprimer les références brisées :
    find .git/refs -size 0 -delete -print

  3. Réparer le référentiel à partir d'un ou plusieurs sites distants :
    git-repair --force

  4. Nettoyer les commits qui pendent :
    git gc --prune=now

  5. Récupérer le dernier état à distance :
    git fetch

Vous pouvez aussi passer en mode maître et le réinitialiser à origine/maître :
git checkout master
git reset --hard origin/master

Vérifier avec git fsck :
git fsck

-3voto

NoRegrets Points 7

Cette commande a fonctionné pour moi :

git reset --mixed

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X