¿Recuperando el archivo agregado/preparado después de hacer git reset --hard HEAD^?

Resuelto Susheel Javadi asked hace 15 años • 6 respuestas

Agregué un nuevo archivo F1e hice cambios en otro archivo F2 pero luego hice ungit reset --hard HEAD^ y perdí todos los cambios en los archivos.

Hay alguna manera de recuperarlos?

Miré una pregunta relacionada aquí: ¿Cómo puedo deshacer git reset --hard HEAD~1? pero esa pregunta supone que uno ha realizado un compromiso de Git.

Susheel Javadi avatar Jul 10 '09 17:07 Susheel Javadi
Aceptado

Puede (con algo de trabajo) recuperar el estado del archivo en el último "git add <file> ". Puedes usar

$ git fsck --cache --no-reflogs --lost-found --dangling HEAD

y luego examine los archivos en el directorio '.git/lost-found/other'.

Lea la página de manual de git fsck .

Jakub Narębski avatar Jul 10 '2009 13:07 Jakub Narębski

(Supongo que el archivo que falta no forma parte de ninguna confirmación. De lo contrario, git log --all -g --diff-filter=D --states tu amigo).

  1. Obtenga una lista de archivos inalcanzables que gitconocen un nombre de archivo:

    git fsck --unreachable --no-reflogs --no-cache HEAD | fgrep " tree " \
    | cut -d " " -f3 | xargs -r -n1 git ls-tree \
    | fgrep " blob " | cut -d " " -f 3- | sort -k2 -u
    
  2. Si ve algo interesante, git cat-file blob SHA-1-of-interesting-filegenerará el archivo en la salida estándar. (Ejemplo: git cat-file blob b8f0bdf56 > recovered-logo.png)

Desafortunadamente, si el archivo que falta no forma parte de ninguna confirmación, git no tiene una marca de tiempo y, como tal, no puede imprimir varias versiones de archivos ordenados por tiempo.

Si el archivo que falta nunca ha sido preparado ( git stageo git add) o escondido ( git stash), no tienes suerte porque, hasta donde sabe git, el archivo nunca existió. (Aún puedes intentar hacer un git fsck --no-reflogs --lost-foundy buscar en el directorio .git/lost-found/otherpara ver si tienes algo que valga la pena conservar en caso de que git tenga una copia de tu archivo faltante por algún accidente afortunado. No tienes nombres de archivos que te ayuden en este caso, solo contenido del archivo.)

En caso de que hayas perdido algunas confirmaciones (en lugar de solo archivos), probablemente querrás ejecutar algo como esto:

gitk --all $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )

Eso se ejecutará gitkcon todas las ramas, todos los reflog y todas las confirmaciones pendientes. Es posible que desee agregar -n 10000algún otro límite en caso de que su repositorio tenga muchas confirmaciones (por ejemplo, kernel de Linux). Si no lo tiene gitk, puede ejecutar una versión menor usando solo una línea de comando como esta:

git log --all --decorate --stat --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )

o una versión con salida menos detallada

git log --all --decorate --oneline --graph --date-order $( git fsck | awk '/dangling commit/ {print $3}'; git log -g --pretty='format:%H' )

Si ve algún compromiso que desea guardar como rama recovered1, simplemente hágalo git checkout -b recovered1 <sha1-of-the-commit>.

Mikko Rantalainen avatar Mar 18 '2013 08:03 Mikko Rantalainen