Debería poder recuperar cualquier archivo que haya agregado al índice (por ejemplo, como en su situación, con git add .
), aunque puede ser un poco complicado. Para agregar un archivo al índice, git lo agrega a la base de datos del objeto, lo que significa que se puede recuperar siempre que no se haya realizado la recolección de basura. Hay un ejemplo de cómo hacer esto en la respuesta de Jakub Narębski aquí:
Sin embargo, probé eso en un repositorio de prueba y hubo un par de problemas, --cached
debería ser --cache
, y descubrí que en realidad no creaba el .git/lost-found
directorio. Sin embargo, los siguientes pasos funcionaron para mí:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
Eso debería generar todos los objetos en la base de datos de objetos que no son accesibles por ninguna referencia, en el índice o mediante el reflog. La salida se verá así:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
... y para cada una de esas manchas, puede hacer:
git show 907b308
Para generar el contenido del archivo.
¿Demasiada producción?
Actualización en respuesta al comentario de sehe a continuación:
Si encuentra que tiene muchas confirmaciones y árboles enumerados en la salida de ese comando, es posible que desee eliminar de la salida todos los objetos a los que se hace referencia de las confirmaciones no referenciadas. (Por lo general, puede volver a estas confirmaciones a través del reflog de todos modos; solo nos interesan los objetos que se han agregado al índice pero que nunca se pueden encontrar a través de una confirmación).
Primero, guarde la salida del comando, con:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all
Ahora los nombres de objeto de esas confirmaciones inalcanzables se pueden encontrar con:
egrep commit all | cut -d ' ' -f 3
De modo que puede encontrar solo los árboles y objetos que se han agregado al índice, pero que no se han confirmado en ningún momento, con:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
$(egrep commit all | cut -d ' ' -f 3)
Eso reduce enormemente la cantidad de objetos que tendrá que considerar.
Actualización: Philip Oakley a continuación sugiere otra forma de reducir la cantidad de objetos a considerar, que es simplemente considerar los archivos modificados más recientemente .git/objects
. Puede encontrar estos con:
find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort
(Encontré esa find
invocación aquí ). El final de esa lista podría verse así:
2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a
En cuyo caso puede ver esos objetos con:
git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a
(Tenga en cuenta que debe eliminar el /
al final de la ruta para obtener el nombre del objeto).