Frecuentemente uso git stash
y git stash pop
para guardar y restaurar cambios en mi árbol de trabajo. Ayer tuve algunos cambios en mi árbol de trabajo que había escondido y reventado, y luego hice más cambios en mi árbol de trabajo. Me gustaría volver y revisar los cambios ocultos de ayer, pero git stash pop
parece eliminar todas las referencias a la confirmación asociada.
Sé que si lo uso git stash
, .git / refs / stash contiene la referencia de la confirmación utilizada para crear el alijo. Y .git / logs / refs / stash contiene todo el alijo. Pero esas referencias se han ido después git stash pop
. Sé que el commit todavía está en mi repositorio en alguna parte, pero no sé qué era.
¿Hay una manera fácil de recuperar la referencia de confirmación de escondite de ayer?
Tenga en cuenta que esto no es crítico para mí hoy porque tengo copias de seguridad diarias y puedo volver al árbol de trabajo de ayer para obtener mis cambios. Estoy preguntando porque debe haber una manera más fácil!
git stash pop
, puedes hacerlo en sugit stash apply
lugar. Hace lo mismo, excepto que no elimina la referencia al alijo aplicado.git stash
,git pull -r upstream
,git push -f origin
,git stash pop
, y el pop dijo "fatal: registro de árbitros / alijo está vacía". 😲 Intenté muchas de estas respuestas, nada funcionó. Cuando miré en .git / refs / stash , el SHA estaba allí. ¿Quizás un problema al marcar una unidad de red de Windows para la sincronización sin conexión? 🤷♂️Respuestas:
Una vez que conozca el hash de la confirmación de alijo que eliminó, puede aplicarlo como alijo:
O bien, puede crear una rama separada para ello con
Después de eso, puedes hacer lo que quieras con todas las herramientas normales. Cuando termines, simplemente vuela la rama.
Encontrar el hash
Si acaba de abrirlo y el terminal sigue abierto, aún tendrá el valor hash impreso
git stash pop
en la pantalla (gracias, Dolda).De lo contrario, puede encontrarlo usando esto para Linux, Unix o Git Bash para Windows:
... o usando Powershell para Windows:
Esto le mostrará todas las confirmaciones en los consejos de su gráfico de confirmación que ya no se hace referencia desde ninguna rama o etiqueta: cada confirmación perdida, incluida cada confirmación de ocultación que haya creado, estará en algún lugar de ese gráfico.
La forma más fácil de encontrar la confirmación de almacenamiento que desea es pasar esa lista a
gitk
:... o vea la respuesta de emragins si usa Powershell para Windows.
Esto lanzará un navegador de repositorio que le mostrará todas las confirmaciones en el repositorio , independientemente de si es accesible o no.
Puede reemplazar
gitk
allí con algo comogit log --graph --oneline --decorate
si prefiere un buen gráfico en la consola en lugar de una aplicación GUI separada.Para detectar las confirmaciones de ocultación, busque mensajes de confirmación de esta forma:
WIP en somebranch : commithash Algún mensaje de confirmación antiguo
Nota : El mensaje de confirmación solo estará en este formulario (comenzando con "WIP on") si no proporcionó un mensaje cuando lo hizo
git stash
.fuente
%{ $_.Split(' ')[2]; }
debería hacer el equivalente del comando{print $3}
en eseawk
comando en PowerShell, pero no tengo un sistema de Windows para probar eso, y todavía necesita un equivalente para la/dangling commit/
parte. De todos modos, solo corregit fsck --no-reflog
y mira la salida. Desea los hashes de las líneas "colgando commit <commitID>".git stash save "<message>"
).git fsck --no-reflog | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ci %H" | sort
la última entrada es probablemente la que deseastash apply
.git stash apply {ref}
restaurado un alijo caído!git
es tan genial que debería ser ilegal!Si no cerró la terminal, solo mire la salida desde
git stash pop
y tendrá el ID del objeto del alijo que se cayó. Normalmente se ve así:(Tenga en cuenta que
git stash drop
también produce la misma línea).Para recuperar ese alijo, solo corre
git branch tmp 2cae03e
, y lo obtendrás como una rama. Para convertir esto en un alijo, ejecuta:Tenerlo como una rama también le permite manipularlo libremente; por ejemplo, para seleccionarlo o fusionarlo.
fuente
git stash apply commitid
a continuacióngit stash
para obtener un nuevo escondite.git stash pop
, tampoco se perderá el alijo, por lo que normalmente no es un problema.git stash pop
. Si desea aplicar el alijo sin soltarlo, usegit stash apply
en su lugar. Además, si desea aplicar un cambio a varias ramas, también puede elegir la confirmación.Solo quería mencionar esta adición a la solución aceptada. No fue inmediatamente obvio para mí la primera vez que probé este método (tal vez debería haber sido), pero para aplicar el alijo desde el valor hash, simplemente use "git stash apply":
Cuando era nuevo en git, esto no estaba claro para mí, y estaba probando diferentes combinaciones de "git show", "git apply", "patch", etc.
fuente
Para obtener la lista de escondites que todavía están en su repositorio, pero que ya no son accesibles:
Si le dio un título a su alijo, reemplace "WIP"
-grep=WIP
al final del comando con una parte de su mensaje, por ejemplo-grep=Tesselation
.El comando es grepping para "WIP" porque el mensaje de confirmación predeterminado para un alijo está en el formulario
WIP on mybranch: [previous-commit-hash] Message of the previous commit.
fuente
!
).Acabo de construir un comando que me ayudó a encontrar mi confirmación de alijo perdido:
Esto enumera todos los objetos en el árbol .git / objects, localiza los que son de tipo commit, luego muestra un resumen de cada uno. Desde este punto, solo era cuestión de revisar los commits para encontrar un "WIP en el trabajo apropiado: 6a9bb2" ("work" es mi rama, 619bb2 es un commit reciente).
Observo que si uso "git stash apply" en lugar de "git stash pop", no tendría este problema, y si uso "git stash save message ", la confirmación podría haber sido más fácil de encontrar.
Actualización: con la idea de Nathan, esto se acorta:
fuente
git fsck --unreachable | grep commit
debería mostrar el sha1, aunque la lista que devuelve puede ser bastante grande.git show <sha1>
mostrará si es la confirmación que desea.git cherry-pick -m 1 <sha1>
fusionará el commit en la rama actual.fuente
Windows PowerShell equivalente usando gitk:
gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })
Probablemente hay una forma más eficiente de hacer esto en una tubería, pero esto hace el trabajo.
fuente
Si desea recuperar un alijo perdido, primero debe encontrar el hash de su alijo perdido.
Como Aristóteles Pagaltzis sugirió que
git fsck
debería ayudarte.Personalmente utilizo mi
log-all
alias que me muestra cada commit (commits recuperables) para tener una mejor visión de la situación:Puede hacer una búsqueda aún más rápida si solo está buscando mensajes "WIP on".
Una vez que conozca su sha1, simplemente cambie su registro de alijo para agregar el alijo anterior:
Probablemente prefiera tener un mensaje asociado para que
-m
E incluso querrás usar esto como un alias:
fuente
-d\\
debería ser-d\
(o incluso más claro-d' '
)git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721
Me gustó el enfoque de Aristóteles, pero no me gustó usar GITK ... ya que estoy acostumbrado a usar GIT desde la línea de comandos.
En cambio, tomé las confirmaciones colgantes y envié el código a un archivo DIFF para su revisión en mi editor de código.
Ahora puede cargar el archivo diff / txt resultante (está en su carpeta de inicio) en su editor txt y ver el código real y el SHA resultante.
Entonces solo usa
fuente
Puede enumerar todas las confirmaciones inalcanzables escribiendo este comando en la terminal:
Comprobar hash de confirmación inalcanzable -
Finalmente aplique si encuentra el artículo escondido -
fuente
¿Por qué la gente hace esta pregunta? Porque aún no conocen ni entienden el reflog.
La mayoría de las respuestas a esta pregunta dan comandos largos con opciones que casi nadie recordará. Entonces las personas entran en esta pregunta y copian y pegan lo que creen que necesitan y lo olvidan casi inmediatamente después.
Aconsejaría a todos con esta pregunta que solo revisen el reflog (git reflog), no mucho más que eso. Una vez que vea esa lista de todas las confirmaciones, hay cientos de formas de averiguar qué confirmación está buscando y seleccionarla o crear una rama a partir de ella. En el proceso, habrá aprendido sobre el reflog y las opciones útiles para varios comandos básicos de git.
fuente
En OSX con git v2.6.4, simplemente ejecuto git stash drop accidentalmente, luego lo encontré siguiendo los pasos a continuación
Si sabes el nombre del alijo, usa:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>
de lo contrario, encontrará la identificación del resultado manualmente con:
$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show
Luego, cuando encuentre el commit-id, simplemente presione el git stash apply {commit-id}
Espero que esto ayude a alguien rápidamente
fuente
Quiero agregar a la solución aceptada otra buena forma de realizar todos los cambios, cuando no tienes gitk disponible o no hay X para la salida.
Luego obtienes todas las diferencias para los hashes que se muestran uno tras otro. Presione 'q' para llegar a la siguiente diferencia.
fuente
No pude obtener ninguna de las respuestas para trabajar en Windows en una simple ventana de comandos (Windows 7 en mi caso).
awk
,grep
ySelect-string
no fueron reconocidos como comandos. Así que probé un enfoque diferente:git fsck --unreachable | findstr "commit"
start cmd /k git show
se verá algo así:
start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e
git stash apply (your hash)
Puede que no sea la mejor solución, pero funcionó para mí
fuente
La respuesta aceptada por Aristóteles mostrará todas las confirmaciones accesibles, incluidas las confirmaciones que no son de tipo oculto. Para filtrar el ruido:
Esto solo incluirá confirmaciones que tienen exactamente 3 confirmaciones principales (que tendrá un alijo), y cuyo mensaje incluye "WIP on".
Tenga en cuenta que si guardó su alijo con un mensaje (por ejemplo
git stash save "My newly created stash"
), esto anulará el mensaje predeterminado "WIP on ...".Puede mostrar más información sobre cada confirmación, por ejemplo, mostrar el mensaje de confirmación o pasarlo a
git stash show
:fuente
Mi favorito es este de una sola línea:
Esta es básicamente la misma idea que esta respuesta, pero mucho más corta. Por supuesto, aún puede agregar
--graph
para obtener una visualización en forma de árbol.Cuando haya encontrado la confirmación en la lista, solicite con
Para mí, el uso
--no-reflogs
reveló la entrada de alijo perdida, pero--unreachable
(como se encuentra en muchas otras respuestas) no lo hizo.Ejecútelo en git bash cuando esté bajo Windows.
Créditos: los detalles de los comandos anteriores se toman de https://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf
fuente
Lo recuperó utilizando los siguientes pasos:
Identifique el código hash de escondite eliminado:
gitk --all $ (git fsck --no-reflog | awk '/ dangling commit / {print $ 3}')
Cherry Pick the Stash:
git cherry-pick -m 1 $ stash_hash_code
Resolver conflictos si los hay usando:
git mergetool
Además, es posible que tenga problemas con el mensaje de confirmación si está utilizando gerrit. Guarde sus cambios antes de seguir las siguientes alternativas:
fuente
Lo que vine a buscar aquí es cómo recuperar el alijo, independientemente de lo que haya verificado. En particular, había escondido algo, luego revisé una versión anterior, luego lo expulsé, pero el alijo no funcionaba en ese momento anterior, por lo que el alijo desapareció; No podía simplemente hacer
git stash
que volviera a la pila. Esto funcionó para mí:En retrospectiva, debería haber estado usando
git stash apply
nogit stash pop
. Estaba haciendo unabisect
y tenía un pequeño parche que quería aplicar en cadabisect
paso. Ahora estoy haciendo esto:fuente
stash apply
.