tag - ¿Cómo recuperar objetos Git dañados por fallas en el disco duro?
qué tipos de etiquetas existen en git (7)
Aquí hay dos funciones que pueden ser útiles si la copia de seguridad está dañada o también tiene algunas copias de seguridad parcialmente dañadas (esto puede suceder si hace una copia de seguridad de los objetos dañados).
Ejecute ambos en el repositorio que está tratando de recuperar.
Advertencia estándar: solo úsela si está realmente desesperado y ha hecho una copia de seguridad de su repositorio (corrupto). Esto podría no resolver nada, pero al menos debería resaltar el nivel de corrupción.
fsck_rm_corrupted() {
corrupted=''a''
while [ "$corrupted" ]; do
corrupted=$( /
git fsck --full --no-dangling 2>&1 >/dev/null /
| grep ''stored in'' /
| sed -r ''s:.*(/.git/.*)/).*:/1:'' /
)
echo "$corrupted"
rm -f "$corrupted"
done
}
if [ -z "$1" ] || [ ! -d "$1" ]; then
echo "''$1'' is not a directory. Please provide the directory of the git repo"
exit 1
fi
pushd "$1" >/dev/null
fsck_rm_corrupted
popd >/dev/null
y
unpack_rm_corrupted() {
corrupted=''a''
while [ "$corrupted" ]; do
corrupted=$( /
git unpack-objects -r < "$1" 2>&1 >/dev/null /
| grep ''stored in'' /
| sed -r ''s:.*(/.git/.*)/).*:/1:'' /
)
echo "$corrupted"
rm -f "$corrupted"
done
}
if [ -z "$1" ] || [ ! -d "$1" ]; then
echo "''$1'' is not a directory. Please provide the directory of the git repo"
exit 1
fi
for p in $1/objects/pack/pack-*.pack; do
echo "$p"
unpack_rm_corrupted "$p"
done
Tuve una falla en el disco duro que ocasionó daños en algunos archivos de un repositorio de Git. Cuando git fsck --full
obtengo el siguiente resultado:
error: .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack SHA1 checksum mismatch
error: index CRC mismatch for object 6c8cae4994b5ec7891ccb1527d30634997a978ee from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack at offset 97824129
error: inflate: data stream error (invalid code lengths set)
error: cannot unpack 6c8cae4994b5ec7891ccb1527d30634997a978ee from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack at offset 97824129
error: inflate: data stream error (invalid stored block lengths)
error: failed to read object 0dcf6723cc69cc7f91d4a7432d0f1a1f05e77eaa at offset 276988017 from .git/objects/pack/pack-6863e0a0e4b4ded6090fac5d12eba6ca7346b19c.pack
fatal: object 0dcf6723cc69cc7f91d4a7432d0f1a1f05e77eaa is corrupted
Tengo copias de seguridad del repositorio, pero la única copia de seguridad que incluye el archivo del paquete ya está dañado. Así que creo que tengo que encontrar una manera de recuperar los objetos individuales de diferentes copias de seguridad y de alguna manera ordenar a Git que produzca un nuevo paquete con solo objetos correctos.
¿Puedes darme pistas sobre cómo arreglar mi repositorio?
El proceso de pago de Git puede seleccionar archivos individuales de una revisión. Simplemente dele el hash de confirmación y el nombre del archivo. Información más detallada here.
Supongo que la manera más fácil de arreglar esto de forma segura es volver a la copia de seguridad más reciente sin compromiso y luego seleccionar selectivamente los archivos no corruptos de las confirmaciones más recientes. ¡Buena suerte!
En algunas copias de seguridad anteriores, es posible que los objetos incorrectos se hayan empaquetado en archivos diferentes o que aún sean objetos sueltos. Entonces tus objetos pueden ser recuperados.
Parece que hay algunos objetos malos en su base de datos. Entonces podrías hacerlo de forma manual.
Debido a git hash-object
, git mktree
y git commit-tree
no escriben los objetos porque se encuentran en el paquete, y luego comienzan a hacer esto:
mv .git/objects/pack/* <somewhere>
for i in <somewhere>/*.pack; do
git unpack-objects -r < $i
done
rm <somewhere>/*
(Sus paquetes se sacan del repositorio y se vuelven a desempacar, solo los objetos buenos están ahora en la base de datos)
Tu puedes hacer:
git cat-file -t 6c8cae4994b5ec7891ccb1527d30634997a978ee
y verifica el tipo del objeto.
Si el tipo es blob: recupera el contenido del archivo de copias de seguridad previas (con git show
o git cat-file
o git unpack-file
; entonces puedes git hash-object -w
para reescribir el objeto en tu repositorio actual).
Si el tipo es tree: puede usar git ls-tree
para recuperar el árbol de copias de seguridad anteriores; luego git mktree
para escribirlo nuevamente en su repositorio actual.
Si el tipo es commit: lo mismo con git show
, git cat-file
y git commit-tree
.
Por supuesto, haría una copia de seguridad de su copia de trabajo original antes de comenzar este proceso.
Además, eche un vistazo a Cómo recuperar el objeto blob corrupto .
Estos son los pasos que seguí para recuperar un objeto blob corrupto.
1) Identificar blob corrupto
git fsck --full
error: inflate: data stream error (incorrect data check)
error: sha1 mismatch 241091723c324aed77b2d35f97a05e856b319efd
error: 241091723c324aed77b2d35f97a05e856b319efd: object corrupt or missing
...
La mancha corrupta es 241091723c324aed77b2d35f97a05e856b319efd
2) Mueva blob corrupto a un lugar seguro (por si acaso)
mv .git/objects/24/1091723c324aed77b2d35f97a05e856b319efd ../24/
3) Obtener padre de blob corrupto
git fsck --full
Checking object directories: 100% (256/256), done.
Checking objects: 100% (70321/70321), done.
broken link from tree 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180
to blob 241091723c324aed77b2d35f97a05e856b319efd
El hash principal es 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180 .
4) Obtener el nombre del archivo correspondiente a blob corrupto
git ls-tree 0716831e1a6c8d3e6b2b541d21c4748cc0ce7180
...
100644 blob 241091723c324aed77b2d35f97a05e856b319efd dump.tar.gz
...
Encuentre este archivo en particular en una copia de seguridad o en el repositorio upstream de git (en mi caso es dump.tar.gz ). Luego, cópielo en algún lugar dentro de su repositorio local.
5) Agregue el archivo previamente dañado en la base de datos de objetos git
git hash-object -w dump.tar.gz
6) ¡Celebra!
git gc
Counting objects: 75197, done.
Compressing objects: 100% (21805/21805), done.
Writing objects: 100% (75197/75197), done.
Total 75197 (delta 52999), reused 69857 (delta 49296)
He resuelto este problema para agregar algunos cambios como git add -A y git commit again.
Pruebe los siguientes comandos al principio (vuelva a ejecutar de nuevo si es necesario):
$ git fsck --full
$ git gc
$ git gc --prune=today
$ git fetch --all
$ git pull --rebase
Y entonces usted todavía tiene los problemas, intente puede:
eliminar todos los objetos corruptos, por ejemplo
fatal: loose object 91c5...51e5 (stored in .git/objects/06/91c5...51e5) is corrupt $ rm -v .git/objects/06/91c5...51e5
eliminar todos los objetos vacíos, por ejemplo
error: object file .git/objects/06/91c5...51e5 is empty $ find .git/objects/ -size 0 -exec rm -vf "{}" /;
verifique un mensaje de "enlace roto" por:
git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
¡Esto te dirá de qué archivo vino la gota corrupta!
para recuperar el archivo, puede ser realmente afortunado, y puede ser la versión que ya ha desprotegido en su árbol de trabajo:
git hash-object -w my-magic-file
de nuevo, y si emite el SHA1 (4b945 ..) que falta, ¡ya está todo listo!
suponiendo que era una versión anterior que se rompió, la forma más fácil de hacerlo es hacer:
git log --raw --all --full-history -- subdirectory/my-magic-file
y eso le mostrará el registro completo de ese archivo (tenga en cuenta que el árbol que tenía puede no ser el árbol de nivel superior, por lo que debe averiguar en qué subdirectorio estaba), entonces puede volver a crear el archivo. Objeto perdido con hash-object nuevamente.
para obtener una lista de todos los árbitros con compromisos faltantes, árboles o blobs:
$ git for-each-ref --format=''%(refname)'' | while read ref; do git rev-list --objects $ref >/dev/null || echo "in $ref"; done
Puede que no sea posible eliminar algunos de esos refs con los comandos normales de ramificación -d o de etiqueta -d, ya que morirán si git nota la corrupción. Entonces use el comando de plomería git update-ref -d $ ref en su lugar. Tenga en cuenta que en el caso de las sucursales locales, este comando puede dejar atrás la configuración de la rama obsoleta en .git / config. Se puede eliminar manualmente (busque la sección [branch "$ ref"]).
Después de que todas las referencias estén limpias, es posible que aún haya commits rotos en el reflog. Puede borrar todos los reflogs usando git reflog expire --expire = now --all. Si no quiere perder todos sus reflogs, puede buscar los Refs individuales para reflogs rotos:
$ (echo HEAD; git for-each-ref --format=''%(refname)'') | while read ref; do git rev-list -g --objects $ref >/dev/null || echo "in $ref"; done
(Tenga en cuenta la opción -g añadida a git rev-list). Luego, use git reflog expire --expire = now $ ref en cada uno de ellos. Cuando todos los refs y reflogs rotos se hayan ido, ejecute git fsck --full para verificar que el repositorio esté limpio. Los objetos colgantes están bien.
A continuación puede encontrar un uso avanzado de los comandos que potencialmente pueden causar la pérdida de sus datos en su repositorio de git si no se utilizan con prudencia, por lo que realice una copia de seguridad antes de que accidentalmente haga más daños a su git. Pruebe su propio riesgo si sabe lo que está haciendo.
Para tirar de la rama actual en la parte superior de la rama ascendente después de ir a buscar:
$ git pull --rebase
También puede intentar extraer una nueva sucursal y eliminar la anterior:
$ git checkout -b new_master origin/master
Para encontrar el objeto dañado en git para su eliminación, intente con el siguiente comando:
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
Para OSX, use sed -E
lugar de sed -r
.
Otra idea es descomprimir todos los objetos de los archivos del paquete para regenerar todos los objetos dentro de .git / objects, así que intente ejecutar los siguientes comandos dentro de su repositorio:
$ 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 lo anterior no ayuda, puede intentar sincronizar o copiar los objetos git de otro repositorio, por ej.
$ 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
Para arreglar la rama rota al intentar realizar el pago de la siguiente manera:
$ git checkout -f master
fatal: unable to read tree 5ace24d474a9535ddd5e6a6c6a1ef480aecf2625
Intenta eliminarlo y pagar desde la parte superior de nuevo:
$ git branch -D master
$ git checkout -b master github/master
En caso de que si git te lleva a un estado separado, revisa el master
y confúngalo en la rama separada.
Otra idea es volver a establecer la base del maestro existente recursivamente:
$ git reset HEAD --hard
$ git rebase -s recursive -X theirs origin/master
Ver también:
- Algunos trucos para reconstruir objetos blob para arreglar un repositorio dañado.
- ¿Cómo arreglar un repositorio roto?
- ¿Cómo eliminar todas las referencias rotas de un repositorio?
- ¿Cómo arreglar el repositorio git corrupto? (seeques)
- ¿Cómo arreglar el repositorio git corrupto? (qnundrum)
- Error al usar SourceTree con Git: ''Resumen'' falló con el código 128: fatal: no se puede leer el árbol
- Recuperar un repositorio corrupto de Git Bare
- Recuperando un repositorio git dañado
- Cómo reparar el error de git: el objeto está vacío / corrupto
- Cómo diagnosticar y corregir git fatal: no se puede leer el árbol
- Cómo lidiar con este error de git
- ¿Cómo arreglar el repositorio git corrupto?
- ¿Cómo ''sobrescribo'', en lugar de ''fusionar'', una rama en otra rama en Git?
- ¿Cómo reemplazar la rama principal en git, por completo, desde otra rama?
- Git: "Objeto suelto corrupto"
- Git reset = fatal: no se puede leer el árbol
Banengusk me estaba poniendo en el camino correcto. Para mayor referencia, quiero publicar los pasos que tomé para corregir mi corrupción del repositorio. Tuve la suerte de encontrar todos los objetos necesarios en paquetes anteriores o en copias de seguridad de repositorios.
# Unpack last non-corrupted pack
$ mv .git/objects/pack .git/objects/pack.old
$ git unpack-objects -r < .git/objects/pack.old/pack-012066c998b2d171913aeb5bf0719fd4655fa7d0.pack
$ git log
fatal: bad object HEAD
$ cat .git/HEAD
ref: refs/heads/master
$ ls .git/refs/heads/
$ cat .git/packed-refs
# pack-refs with: peeled
aa268a069add6d71e162c4e2455c1b690079c8c1 refs/heads/master
$ git fsck --full
error: HEAD: invalid sha1 pointer aa268a069add6d71e162c4e2455c1b690079c8c1
error: refs/heads/master does not point to a valid object!
missing blob 75405ef0e6f66e48c1ff836786ff110efa33a919
missing blob 27c4611ffbc3c32712a395910a96052a3de67c9b
dangling tree 30473f109d87f4bcde612a2b9a204c3e322cb0dc
# Copy HEAD object from backup of repository
$ cp repobackup/.git/objects/aa/268a069add6d71e162c4e2455c1b690079c8c1 .git/objects/aa
# Now copy all missing objects from backup of repository and run "git fsck --full" afterwards
# Repeat until git fsck --full only reports dangling objects
# Now garbage collect repo
$ git gc
warning: reflog of ''HEAD'' references pruned commits
warning: reflog of ''refs/heads/master'' references pruned commits
Counting objects: 3992, done.
Delta compression using 2 threads.
fatal: object bf1c4953c0ea4a045bf0975a916b53d247e7ca94 inconsistent object length (6093 vs 415232)
error: failed to run repack
# Check reflogs...
$ git reflog
# ...then clean
$ git reflog expire --expire=0 --all
# Now garbage collect again
$ git gc
Counting objects: 3992, done.
Delta compression using 2 threads.
Compressing objects: 100% (3970/3970), done.
Writing objects: 100% (3992/3992), done.
Total 3992 (delta 2060), reused 0 (delta 0)
Removing duplicate objects: 100% (256/256), done.
# Done!