remote - git push origin master
¿Cómo restaurar un objeto dañado en un repositorio git(para novatos)? (3)
He intentado abrir mi repositorio hoy y no he encontrado ningún historial de confirmación. Todo lo que probé (estado de git, registro de git, comprobación de git ...) arrojó un error sobre un objeto dañado.
Investigué este problema en línea y encontré el article de Linus Torvalds, pero me perdí en el momento en que encontró el ID de enlace roto: ninguna de mis ID de archivo, árbol o blob, coincide con la ID del culpable que aparece en el mensaje de error.
Luego volví al artículo sobre la recuperación de "objetos git dañados por un fallo en el disco duro" y (después de mover el objeto culpable) me abrí paso hasta
$ cat packed-refs
en qué punto mi computadora dijo: cat: packed-refs: No such file or directory
he guardado ese paso cat: packed-refs: No such file or directory
, e hice el
$ git fsck --full
y obtuve el resultado adecuado, pero luego se suponía que debía copiar al culpable (o a lo que me refería como culpable, el ID de sha1 generado por el error) desde un repositorio de respaldo al repositorio principal, luego copiar los objetos faltantes el repositorio de respaldo en el repositorio principal, por lo que puedo decir; y no quiero hacer nada demasiado drástico o podría forzar algo que no puedo deshacer después.
Entonces, mi (s) pregunta (s) es (es), ¿se supone que hice una copia de seguridad ( ooh, alerta de novato ), o fue eso lo que ocurrió cuando desempaqué el archivo. ¿Y el "culpable" que estoy copiando en realidad es un archivo limpio, es decir, no está dañado?
(Creo que es justo decirle que al principio me confundí con un guión simple en el archivo de Torvalds entre "git" y "fsck". Entonces, soy REALMENTE nuevo en esto).
Lista de errores
Error original:
$ git status
fatal: object 016660b7605cfc2da85f631bbe809f7cb7962608 is corrupted
Error después de mover el objeto 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 mover el objeto dañado de nuevo:
$ 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 mover el archivo hacia atrás:
$ 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 archivo .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 mensaje de error que el objeto dañado que movió fue un compromiso. (¡HEAD lo estaba apuntando!) Desafortunadamente, esto significa que es difícil repararlo manualmente. (Por "difícil" quiero decir que es imposible a menos que pueda recordar exactamente cuál era el mensaje de confirmación y la hora en que realizó la confirmación). Afortunadamente, esto significa que es fácil resucitar una nueva confirmación con el mismo contenido de archivo. Solo hay que escribir un nuevo mensaje para ello.
Antes de comenzar, eche un vistazo al contenido de .git/HEAD
. Si es un nombre de rama, recuérdelo para más adelante.
Primero, tenemos que averiguar cuál fue el padre de este compromiso debería haber sido. Puede usar git reflog
para mirar el reflog de HEAD, y encontrar el SHA1 de donde estaba HEAD justo antes de realizar el commit 016660b. Debería verse algo como esto:
016660b HEAD@{n}: commit: <subject of commit>
1234abc HEAD@{n-1}: ...
Puede copiar el SHA1 de la posición anterior de HEAD y verificar ese compromiso:
git checkout 1234abc
Luego puede leer en el árbol que tenía su confirmación dañada:
git read-tree 2c1033501b82e301d47dbf53ba0a199003af25a8
Y luego cometer!
git commit
Ahora, hay algunas preguntas aquí sobre qué debería haber pasado con sus sucursales. Si HEAD estaba apuntando a una rama (digamos maestro) que a su vez apuntaba a la confirmación dañada, definitivamente queremos arreglar eso:
git branch -d master # remove the original master branch
git checkout -b master # recreate it here
Si hay otras ramas que contenían la confirmación dañada, también tendrá que restaurarlas. Avíseme si necesita ayuda con eso.
FWIW, aquí hay una respuesta que es más práctica que la mayoría de los optimistas sin esperanzas en otras preguntas sobre los git
corruptos, la mayoría de los cuales hacen la suposición sin fundamento de que el OP pobre 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 intento de ejecutar un simple git gc --aggressive
reveló que, sin que yo lo supiera, en algún momento mi - completamente local - git
repo se había vuelto completamente flexible: no se pudo registrar nada más allá de hace unos meses, 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 objetos fueron identificados como perdidos por git fsck
.
git-repair
: minimizando el trabajo manual aterrador desde 2014
Después de entrar en pánico y encontrar un montón de preguntas con respuestas deficientes y con un voto excesivo, simplemente diga ''¡simplemente vuelva a clonar desde el origen remoto!'' - lo cual, permítanme enfatizar el punto, no tengo porque soy el origen - encontré git-repair
, hice un simple sudo aptitude install git-repair
, y dejé que hiciera todas las tediosas correcciones automatizables que probablemente habría me tomó horas (por favor: ejecute en una copia de su repositorio corrupto [duh], sin --force
!)
Eso ayudó a reducir 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 esto parecía centrarse alrededor de una confirmación que no se podía recuperar. ¿Cómo podría recuperarlo? La búsqueda de desbordamiento de pila no fue de mucha ayuda!
Usted tiene una copia de seguridad, ¿verdad?
Aquí es donde tuve la suerte de tener una copia de seguridad de finales de noviembre. Usted toma copias de seguridad, ¿verdad? En mi caso, fue un zip manual del repositorio (mi rutina diaria de copia de seguridad es una cosa horrible de tar
incremental que en realidad nunca he probado ... a-tos) ... pero, bueno, fue lo suficientemente bueno. No había sufrido la indignidad que había afligido mi repo en vivo.
Pero el objeto faltante no parecía estar simplemente almacenado en el .git/objects/XY/RESTOFHASHBLAHBLAHBLAH
esta copia de seguridad. Eso es probablemente porque era un compromiso, no un archivo. ¡No lo sé! git
es la magia para mí, siempre más allá de mi capacidad de comprensión. Solo necesitaba una solución, rápido. ¿No es por eso que estamos todos aquí?
Recuperar objetos de una copia de seguridad (que tiene, ¿verdad?)
Con la copia de seguridad 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-repaired/.git/objects
inmediatamente encontré que simplemente se ejecutaba ingenuamente cp -fr /path/to/repo_backup/.git/objects/* /path/to/repo_git-repaired/.git/objects
a file-merge el directorio .git/objects
de la copia de seguridad en su contraparte en mi repo corrompido, algo reparado ... trabajé para recuperar toda la historia , de vuelta al buen estado initial commit lol
. Probando la solución: git fsck --full
ahora también estaba feliz (a pesar de todos los bits colgantes).
Luego tomé copias de seguridad de los repositorios en vivo / corruptos, parcialmente reparados y aparentemente recuperados en un disco separado, en caso de que necesite alguno de ellos nuevamente.
Debería verificar la metodología y el comando antes de ejecutarlo, o tal vez encontrar una forma mucho mejor de lo que soy demasiado perezoso para pensar. No lo sé. Pero para mí, salvó mi repo. Y sobre el tema de adivinar lo que digo ...
Renuncias infinitas en combinaciones infinitas.
Ahora, obviamente, todo esto viene con advertencias: debe probar todo en una copia de su repositorio dañado, leer toda la documentación, considerar ser un poco más cuidadoso de lo que era (ese comando cp
forzado) y no responsabilizarme ni responsabilizarme. por absolutamente cualquier cosa que salga mal * ... pero te da algo mejor que probar que ''solo volver a clonar desde el origen remoto'', ¿verdad?
*
Si, sin embargo, todo va bien , una gran donación puede estar en orden. ;)
Si alguien me necesita, estaré mirando con desconfianza en la dirección general de mi unidad de disco, con suerte crearé una rutina de respaldo que no tomará horas de dos dígitos para restaurar (si es que lo hace), y tal vez incluso obtenga algo dormir.
Yo tuve el mismo problema. Sin embargo, mi problema se resolvió cambiando los permisos de las carpetas y subcarpetas .git / objects (recursivamente) en el servidor. Algo como:
chmod -R 770 .git/objects
Creo que ese no es tu problema, pero en mi caso se resolvió.