Deshacer git reset –hard con archivos no confirmados en el área de ensayo

10 minutos de lectura

Deshacer git reset hard con archivos no confirmados en el
eistráti

Estoy tratando de recuperar mi trabajo. estúpidamente lo hice git reset --hardpero antes de eso solo he hecho get add . y no lo hizo git commit. ¡Por favor ayuda! Aquí está mi registro:

MacBookPro:api user$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)

#   modified:   .gitignore
...


MacBookPro:api user$ git reset --hard
HEAD is now at ff546fa added new strucuture for api

¿Es posible deshacer git reset --hard ¿en esta situación?

  • @MarkLongair hombre increíble! ¡Acabas de recuperar mi trabajo! ¡Escribí un script de Python para crear archivos de todos los resultados! Agregaré el script como respuesta.

    – Chico

    8 de enero de 2014 a las 13:47

  • No ‘estúpidamente’… sino ‘ingenuamente’… ¡porque yo hice LO MISMO!

    –Rosdi Kasim

    7 de marzo de 2014 a las 8:34

  • Todavía podría ser estúpidamente 😉

    –Duncan McGregor

    11 de enero de 2016 a las 19:22

  • Aquí hay un gran artículo sobre cómo revertir algo de esto. Va a tomar algo de trabajo manual.

    – Jan Swart

    22 oct 2016 a las 11:05

  • @MarkLongair “` find .git/objects/ -type f -printf ‘%TY-%Tm-%Td %TT %p\n’ | ordenar “` funcionó para mí. También aparecen las fechas, comience a verificar los blobs desde el final.

    – ZAky

    08/04/2018 a las 17:57


1646965751 656 Deshacer git reset hard con archivos no confirmados en el
marca longair

Debería poder recuperar cualquier archivo que haya agregado al índice (p. ej., como en su situación, con git add .) aunque podría ser un poco de trabajo. Para agregar un archivo al índice, git lo agrega a la base de datos de objetos, lo que significa que se puede recuperar siempre que aún no se haya realizado la recolección de elementos no utilizados. Hay un ejemplo de cómo hacer esto en la respuesta de Jakub Narębski aquí:

  • Recuperando el archivo agregado después de hacer git reset –hard HEAD^

Sin embargo, probé eso en un repositorio de prueba y hubo un par de problemas: --cached debiera ser --cachey descubrí que en realidad no creó 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 a los que no puede acceder ninguna referencia, en el índice o mediante el registro de referencia. La salida se verá algo como esto:

unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03

… y para cada uno de esos blobs, puedes hacer:

git show 907b308

Para generar el contenido del archivo.


¿Demasiada salida?

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 cualquier objeto al que se haga referencia desde confirmaciones sin referencia. (Por lo general, puede volver a estas confirmaciones a través del registro de referencia de todos modos; solo estamos interesados ​​​​en los objetos que se agregaron 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

Por lo tanto, puede encontrar solo los árboles y los objetos que se agregaron al índice, pero que no se confirmaron 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.


Actualizar: 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 en .git/objects. Puedes encontrarlos con:

find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort

(Encontre eso 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 puedes ver esos objetos con:

git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a

(Tenga en cuenta que tiene que quitar el / al final de la ruta para obtener el nombre del objeto).

  • ¿No es posible echar un vistazo a las marcas de tiempo de los objetos más recientes que son posteriores a su última confirmación? O me estoy perdiendo algo.

    – Felipe Oakley

    12 de septiembre de 2011 a las 19:22

  • @Philip Oakley: gracias por esa sugerencia, agregué la sugerencia para encontrar los objetos modificados más recientemente en la base de datos de objetos.

    –Mark Longair

    13 de septiembre de 2011 a las 5:42

  • ¡Amigo, eso es increíble! Eso salvó mi @$$ justo ahora. Y aprendí algo de ciencia git. Mejor mira lo que agregas al índice…

    – bowsersenior

    28 de julio de 2012 a las 0:31

  • no robar la luz de cal de nadie aquí. Pero solo como una nota, ya que me encontré con el mismo problema y pensé que había perdido todo mi trabajo. Para aquellos que usan un IDE, los IDE suelen tener una solución de recuperación con un solo clic. En el caso de PHPstorm, solo tenía que hacer clic derecho en el directorio y seleccionar Mostrar historial local y luego volver al último estado válido.

    – Shalom Sam

    22 de septiembre de 2014 a las 4:44

  • Todavía salvando culos 19 años después. Realmente pensé que me había equivocado mucho ahora. Consiguió recuperar todo.

    – Neil

    27 de abril de 2020 a las 12:04

1646965751 560 Deshacer git reset hard con archivos no confirmados en el
ricardo saunders

acabo de hacer un git reset --hard y perdió un compromiso. Pero conocía el hash de confirmación, así que pude hacer git cherry-pick COMMIT_HASH para restaurarlo.

Hice esto a los pocos minutos de perder la confirmación, por lo que puede funcionar para algunos de ustedes.

  • Gracias gracias gracias Logré recuperar un día de trabajo gracias a esta respuesta

    – Danza

    11 de noviembre de 2013 a las 16:24


  • Probablemente valga la pena mencionar que puedes ver esos hashes usando git reflogp.ej git reset --hard -> git reflog (mirando el hash HEAD@{1}) y finalmente git cherry-pick COMMIT_HASH

    – Javier Lopez

    16 de noviembre de 2013 a las 14:11

  • Chicos que leen esto, tengan en cuenta que esto solo funciona para un solo hash de confirmación, si hubo más de una sola confirmación, ¡no resolverá el problema de inmediato!

    – Ain Tohvri

    5 de junio de 2014 a las 0:39

  • De hecho, puede restablecer “adelante”. Entonces, si ha reiniciado varias confirmaciones, hacer otro ‘git reset –hard ‘ debería restaurar toda la cadena de confirmaciones hasta ese punto. (dado que aún no están en GC)

    – Akimsko

    16/09/2014 a las 13:49

  • El one-liner para recuperar confirmaciones perdidas con git reset --hard (suponiendo que no haya hecho nada más después de ese comando) es git reset --hard @{1}

    – Ajedi32

    15/01/2015 a las 18:40

¡Gracias a Mark Longair recuperé mis cosas!

Primero guardé todos los hashes en un archivo:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > allhashes

a continuación, los puse todos (eliminando el ‘blob inalcanzable’) en una lista y puse todos los datos en nuevos archivos… tienes que elegir tus archivos y cambiarles el nombre de nuevo, lo que necesitas… pero solo necesitaba unos pocos archivos… espero que esto ayude a alguien…

commits = ["c2520e04839c05505ef17f985a49ffd42809f",
    "41901be74651829d97f29934f190055ae4e93",
    "50f078c937f07b508a1a73d3566a822927a57",
    "51077d43a3ed6333c8a3616412c9b3b0fb6d4",
    "56e290dc0aaa20e64702357b340d397213cb",
    "5b731d988cfb24500842ec5df84d3e1950c87",
    "9c438e09cf759bf84e109a2f0c18520",
    ...
    ]

from subprocess import call
filename = "file"
i = 1
for c in commits:
    f = open(filename + str(i),"wb")
    call(["git", "show", c],stdout=f)
    i+=1

  • ¡Sí! Esto es exactamente lo que necesitaba. También me gusta el script de Python para recrear todos los archivos. Las otras respuestas me pusieron nervioso por perder mis datos con la recolección de basura, por lo que descargar los archivos es una victoria para mí 🙂

    –Eric Olson

    18 de noviembre de 2014 a las 23:26

  • Escribí este script basado en esta respuesta. Funciona fuera de la caja: github.com/pendashteh/git-recover-index

    – Alexar

    31 de enero de 2016 a las 7:17

  • Me resulta más fácil automatizarlo así: mkdir lost; git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") | grep -Po '\s\S{40}$' | xargs -i echo "git show {} > lost/{}.blob" | sh. Los archivos terminarán en lost/*.blob

    – Matija Nalis

    25 de enero de 2018 a las 17:22

La solución de @ Ajedi32 en los comentarios me funcionó exactamente en esta situación.

git reset --hard @{1}

Tenga en cuenta que todas estas soluciones se basan en que no hay git gc, y algunas de ellas pueden causar uno, por lo que comprimiría el contenido de su directorio .git antes de intentar cualquier cosa para que tenga una instantánea a la que volver si no lo hace. no funciona para ti.

Me encontré con el mismo problema, pero no había agregado los cambios al índice. Entonces, todos los comandos anteriores no me devolvieron los cambios deseados.

Después de todas las elaboradas respuestas anteriores, esta es una pista ingenua, pero puede salvar a alguien que no lo pensó primero, como lo hice yo.

Desesperado, traté de presionar CTRL-Z en mi editor (LightTable), una vez en cada pestaña abierta; afortunadamente, recuperé el archivo en esa pestaña, a su último estado antes del git reset --hard. HH.

  • Exactamente la misma situación, no se agregó el índice y se restableció por completo y ninguna de las soluciones funcionó todo lo anterior. Este fue un movimiento INTELIGENTE, gracias, hice Ctrl+Z y salvé mi día. Mi editor: SublimeText. ¡Uno arriba de mi lado!

    – Vivek

    22 de diciembre de 2017 a las 10:19

Deshacer git reset hard con archivos no confirmados en el
Saikat

Dios mío, me tiré del pelo hasta que me encontré con esta pregunta y sus respuestas. Creo que la respuesta correcta y sucinta a la pregunta formulada solo está disponible si junta dos de los comentarios anteriores, así que aquí está todo en un solo lugar:

  1. Como lo menciona chilicuil, ejecuta git reflog para identificar allí el hash de confirmación al que desea volver

  2. Como lo mencionó akimsko, es probable que NO desee elegir a menos que solo haya perdido una confirmación, por lo que debe ejecutar git reset --hard <hash-commit-you-want>

Nota para los usuarios de egit Eclipse: no pude encontrar una manera de realizar estos pasos dentro de Eclipse con egit. Cerrar Eclipse, ejecutar los comandos anteriores desde una ventana de terminal y luego volver a abrir Eclipse funcionó bien para mí.

  • Exactamente la misma situación, no se agregó el índice y se restableció por completo y ninguna de las soluciones funcionó todo lo anterior. Este fue un movimiento INTELIGENTE, gracias, hice Ctrl+Z y salvé mi día. Mi editor: SublimeText. ¡Uno arriba de mi lado!

    – Vivek

    22 de diciembre de 2017 a las 10:19

1646965752 422 Deshacer git reset hard con archivos no confirmados en el
abyrd

Si está editando sus archivos con un IDE, también puede mantener su propio historial independiente de Git. En algunas circunstancias, es mucho más sencillo omitir Git por completo y usar el IDE. Por ejemplo, IntelliJ IDEA y Eclipse tienen este tipo de control de versión local automatizado, al que se refieren como “historial local”. En IntelliJ es sencillo recuperar un lote completo de cambios perdidos en muchos archivos: en el panel Proyecto, puede hacer clic con el botón derecho en un proyecto completo o en un árbol de directorios y seleccionar Mostrar historial en el submenú Historial local. los git reset --hard debería aparecer en la lista como un “cambio externo” (es decir, desencadenado desde fuera del IDE), y puede usar el botón de reversión o el elemento del menú contextual para revertir todo al estado justo antes de que ocurriera ese cambio externo.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad