¿Cómo se restaura un object dañado en un repository git (para principiantes)?

Traté de abrir mi repository hoy y salió sin historial de compromiso. Todo lo que probé (estado de git, git log, git checkout …) arrojó un error sobre un object corrupto.

Investigué este problema en línea y encontré el artículo de Linus Torvalds, pero me perdí en el punto en que encontró la identificación del enlace roto: ninguno de mis ID de file, tree o blob, coincide con el ID culpable arrojado por el post de error.

Luego volví al artículo sobre la recuperación de "objects GIT dañados por fallas en el disco duro" y (después de mover el object culpable fuera del path) seguí trabajando hasta

$ cat packed-refs 

en ese momento mi computadora dijo: cat: packed-refs: No such file or directory , salté ese paso e hice

 $ git fsck --full 

y obtuve el resultado apropiado, pero luego se suponía que debía copyr el culpable (o lo que yo me refería como el culpable, el identificador sha1 arrojado por el error) desde un repository de respaldo al repository principal, luego copie los objects que faltan el repository de respaldo en el repository principal, hasta donde yo sé; y no quiero hacer nada demasiado drástico o podría forzar algo que no puedo forzar más tarde.

Entonces mi (s) pregunta (s) es (son), ¿se suponía que debería haber hecho una copy de security ( ooh, alerta de novato ), o fue eso lo que sucedió cuando desempaqué el file .pack? ¿Y el "culpable" que estoy copyndo en realidad es un file limpio, es decir, no está dañado?

(Creo que es justo decirte que al principio estaba confundido por una simple carrera en el file de Torvalds entre el "git" y "fsck". Así que soy REALMENTE nuevo en esto).

ERROR

Error original:

 $ git status fatal: object 016660b7605cfc2da85f631bbe809f7cb7962608 is corrupted 

Error después de mover el object corrupto:

 $ git status fatal: bad object HEAD $ git fsck --full error: HEAD: invalid sha1 pointer 016660b7605cfc2da85f631bbe809f7cb7962608 error: refs/heads/RPG does not point to a valid object! dangling tree 2c1033501b82e301d47dbf53ba0a199003af25a8 dangling blob 531aca5783033131441ac7e132789cfcad82d06d dangling blob 74a47ff40a8c5149a8701c2f4b29bba408fa36f5 dangling blob b8df4d9751c0518c3560e650b21a182ea6d7bd5e dangling blob fc2d15aead4bd0c197604a9f9822d265bb986d8b $ git ls-tree 2c1033501b82e301d47dbf53ba0a199003af25a8 040000 tree 4a8b0b3747450085b1cd920c22ec82c18d9311bd folder1 040000 tree 33298295f646e8b378299191ce20b4594f5eb625 folder2 040000 tree dec82bad6283fc7fcc869c20fdea9f8588a2f1b2 folder3 040000 tree 4544967c6b04190f4c95b516ba8a86cab266a872 folder4 $ git ls-tree dec82bad6283fc7fcc869c20fdea9f8588a2f1b2 100644 blob 67bda6df733f6cd76fc0fc4c8a6132d8015591d8 fileA 100644 blob 4cb7272c9e268bfbd83a04e568d7edd87f78589c fileB 100644 blob ce9e0f2cc4d3b656fa30340afbdfed47fe35f3ef fileC $ git ls-tree 4544967c6b04190f4c95b516ba8a86cab266a872 100644 blob d64fe3add8328d81b1f31c9dbd528956ab391fb6 fileD 100644 blob d1ebd7df7082abc5190d87caa821bf3edb7b68e8 fileE 100644 blob bb6cd264e47a3e5bc7beadf35ea13bac86024b02 ... 100644 blob 995d622b9012f4ef69921091d1e1a73f32aa94e6 100644 blob 9141dbd2b1c7931a6461195934b6599f5dfb485a 100644 blob ab128da1d82907cd0568448dc089a7996d5f79d3 100644 blob 57b11a7eb408a79739d2bb60a0dc35c591340d18 100644 blob 118105291c1c6ca4a01744889ffafbb018bc7ed3 100644 blob 86b1dfda56d0603f16910228327751f869d16bdc 100644 blob 077fe0cddde0d0be9d0974f928f66815caca7b76 100644 blob c0b32fd0450f21994bdc53ea83d3cf0bccd74004 100644 blob 37b87a4d11453468c4ae04572db5d322cd2d1d80 100644 blob 79d39f8d4e57fa3a71664598a63b6dfd88149638 100644 blob ee07bbe3e8cb5d6bb79fb0cd52cfbc9bd830498d files $ git ls-tree 33298295f646e8b378299191ce20b4594f5eb625 100644 blob f9d6f45cd028aec97f761f00c5f4f2f6b50fb925 MoreFiles 100644 blob 0cb9eed1d0dd9214d54a03af1bda21f37b8c0d02 100644 blob 198e4f97ece735cce47b7e99b54f1b5fa99fabf5 100644 blob fc004212fa8e483e5a8ab35b508027c7a9a1cbfa 100644 blob 0c7d74c7a9a8337b4a9f20802b63d71d42287f89 $ git ls-tree 4a8b0b3747450085b1cd920c22ec82c18d9311bd 100644 blob 0320f5b23dd7cce677fac60b9ad03f418cff5c88 oneLASTfile 

Después de volver a mover el object dañado:

 $ git log --raw --all fatal: object 016660b7605cfc2da85f631bbe809f7cb7962608 is corrupted $ cat packed-refs cat: packed-refs: No such file or directory $ git fsck --full fatal: object 016660b7605cfc2da85f631bbe809f7cb7962608 is corrupted 

Después de volver a mover el file:

 $ git fsck --full` error: HEAD: invalid sha1 pointer 016660b7605cfc2da85f631bbe809f7cb7962608 error: refs/heads/RPG does not point to a valid object! dangling tree 2c1033501b82e301d47dbf53ba0a199003af25a8 dangling blob 531aca5783033131441ac7e132789cfcad82d06d dangling blob 74a47ff40a8c5149a8701c2f4b29bba408fa36f5 dangling blob b8df4d9751c0518c3560e650b21a182ea6d7bd5e dangling blob fc2d15aead4bd0c197604a9f9822d265bb986d8b 

Después de desempacar el file .pack:

 $ git log fatal: bad object HEAD $ cat packed-refs cat: packed-refs: No such file or directory $ git fsck --full error: HEAD: invalid sha1 pointer 016660b7605cfc2da85f631bbe809f7cb7962608 error: refs/heads/RPG does not point to a valid object! dangling tree 2c1033501b82e301d47dbf53ba0a199003af25a8 dangling blob 531aca5783033131441ac7e132789cfcad82d06d dangling blob 74a47ff40a8c5149a8701c2f4b29bba408fa36f5 dangling blob b8df4d9751c0518c3560e650b21a182ea6d7bd5e dangling blob fc2d15aead4bd0c197604a9f9822d265bb986d8b 

Bueno entonces. Podemos ver en el segundo post de error que el object corrupto que movió fue una confirmación. (¡HEAD lo estaba señalando!) Desafortunadamente, esto significa que es difícil repararlo manualmente. (Por "difícil" quiero decir que probablemente sea imposible a less que puedas recordar exactamente cuál fue el post de compromiso y a qué hora lo hiciste). Afortunadamente, esto significa que es fácil resucitar un nuevo compromiso con el mismo contenido de file: podrás solo tiene que escribir un nuevo post para eso.

Antes de comenzar, eche un vistazo a los contenidos de .git/HEAD : si es un nombre de twig, recuerde eso para más adelante.

Primero, necesitamos averiguar cuál debería haber sido el padre de esta confirmación. Puedes usar git reflog para ver el reflog de HEAD, y encontrar el SHA1 donde HEAD estaba justo antes de que hayas hecho commit 016660b. Debería verse algo como esto:

 016660b HEAD@{n}: commit: <subject of commit> 1234abc HEAD@{n-1}: ... 

Puede copyr el SHA1 de la position anterior de HEAD y verificar que confirme:

 git checkout 1234abc 

Luego puedes leer en el tree que tu commit corrupto tuvo:

 git read-tree 2c1033501b82e301d47dbf53ba0a199003af25a8 

¡Y luego cometer!

 git commit 

Ahora, hay alguna pregunta aquí sobre lo que debería haber sucedido con sus sucursales. Si HEAD estaba apuntando a una twig (digamos master) que a su vez apuntaba a la confirmación corrupta, definitivamente queremos arreglar eso:

 git branch -d master # remove the original master branch git checkout -b master # recreate it here 

Si hay otras twigs que contenían la confirmación corrupta, tendrás que hacer algunas restauraciones en ellas también. Avísame si necesitas ayuda con eso.

Yo tuve el mismo problema. Sin embargo, mi problema se resolvió cambiando los permissions de las carpetas y subcarpetas .git / objects (recursivamente) en el server. Algo como:

 chmod -R 770 .git/objects 

Creo que ese no es tu problema, pero en mi caso se resolvió.

FWIW, aquí hay una respuesta que es más práctica que muchas de las desesperadamente optimistas sobre otras preguntas sobre git corruptos de git , la mayoría de los cuales hacen la suposition infundada de que el pobre OP puede 'simplemente volver a clonar desde el origen remoto'. Hmm. Pero. Espera un segundo. ¿Qué pasa si yo soy el origen ?

El horror

La historia comienza cuando un bash de ejecutar un simple git gc --aggressive reveló que, sin que yo lo supiera, en algún momento mi – completamente local – git repo de alguna manera había sido completamente regado: no fue capaz de registrar nada más allá de unos meses atrás, perdiendo así la mayor parte de su historia, y gritaba guturalmente cuando se le pedía que git fsck --full | grep -v dangling git fsck --full | grep -v dangling . Varios objects fueron identificados como perdidos por git fsck .

git-repair : minimizando el aterrador trabajo manual desde 2014

Después de entrar en pánico y de encontrar muchas preguntas con respuestas pobres que votaron con anterioridad, simplemente decía '¡simplemente vuelve a clonar desde el origen remoto!' – lo cual, déjenme aclarar el punto, no lo tengo porque soy el origen – encontré git-repair , hice un sudo aptitude install git-repair simple sudo aptitude install git-repair , y dejé que hiciera todas las tediosas correcciones automáticas que probablemente hubieran me llevó horas (por favor: ejecute una copy de su repository corrupto [duh], sin --force !)

Eso ayudó a networkingucir la cantidad de horror reportado por git fsck --full | grep -v dangling git fsck --full | grep -v dangling . Pero las cosas más allá de mediados de agosto aún eran inalcanzables.

En particular, todo parecía centrarse en una confirmación que no se pudo recuperar. ¿Cómo podría recuperarlo? ¡La búsqueda del desbordamiento de stack no fue de mucha ayuda!

Usted tiene una copy de security, ¿verdad?

Aquí es donde tuve la suerte de tener una copy de security desde finales de noviembre. Usted toma copys de security, ¿verdad? En mi caso, era un zip manual del repository (mi rutina diaria de respaldo es una horrible cosa incremental de tar que nunca he probado realmente … a-tos) … pero puaj, era lo suficientemente bueno. No había sufrido la indignidad que había afligido a mi repo en vivo.

Pero el object que faltaba no parecía estar almacenado simplemente en .git/objects/XY/RESTOFHASHBLAHBLAHBLAH esta copy de security. Eso es probablemente porque fue una confirmación, no un file. ¡No lo sé! git es magia para mí, para siempre más allá de mi capacidad de comprensión. Solo necesitaba una solución, rápido. ¿No es por eso que todos estamos aquí?

Recuperar objects de una copy de security (que tiene, ¿verdad?)

Con la copy de security ahora en la mano, tuve una idea hilarantemente tonta, dije 'no hay forma de que esto pueda funcionar!', cp -fr /path/to/repo_backup/.git/objects/* /path/to/repo_git-repaird/.git/objects inmediatamente encontré eso simplemente ejecutando ingenuamente cp -fr /path/to/repo_backup/.git/objects/* /path/to/repo_git-repaird/.git/objects al file-fusionar el directory .git/objects de la copy de security en su contraparte en mi repository corrupto, "algo reparado" … funcionó para recuperar toda la historia , volviendo al buen viejo initial commit lol . Demostrando la solución: git fsck --full era feliz (a pesar de todos los bits).

Luego tomé copys de security de los repositorys en vivo / corruptos, parcialmente reparados y aparentemente recuperados en un disco separado, en caso de que necesite alguno de ellos nuevamente.

Debería verificar esa metodología y command antes de ejecutarlo, o tal vez encontrar una manera mucho mejor en la que soy demasiado perezoso para pensar. No lo sé. Pero para mí, salvó mi repo. Y sobre el tema de adivinar lo que digo …

Descargos de responsabilidad infinitos en combinaciones infinitas

Ahora, obviamente, todo esto viene con advertencias: debes probar todo en una copy de tu repository corrupto, leer toda la documentation, considerar ser un poco más cuidadoso que yo (ese command cp forzado), y no hacerme responsable o responsable para cualquier cosa que vaya mal * … pero le da algo mejor para intentar que simplemente "volver a clonar desde el origen remoto", ¿verdad?

* Si, sin embargo, todo va bien , una gran donación puede estar en order. 😉

Si alguien me necesita, miraré con recelo a la dirección general de mi unidad de disco, con la esperanza de encontrar una rutina de copy de security que no requiera dos horas para restaurar (si es que lo hace), y tal vez incluso get alguna dormir.