Cómo recuperar cambios ocultos no confirmados

Resuelto Aswathy P Krishnan asked hace 11 años • 8 respuestas

Tenía algunos cambios no confirmados en mi rama de desarrollo y los escondí usando git stash, pero hubo algunos cambios que fueron muy importantes entre los escondidos. ¿Hay alguna forma de recuperar esos cambios?

Además, desde entonces he realizado algunos cambios además de los archivos de código escondidos.

¿Existe alguna posibilidad de que pueda recuperar los cambios ocultos en una nueva rama si es posible?

Aswathy P Krishnan avatar Sep 25 '13 17:09 Aswathy P Krishnan
Aceptado

La respuesta fácil a la pregunta fácil esgit stash apply

Simplemente revisa la rama en la que deseas realizar los cambios y luego git stash apply. Luego use git diffpara ver el resultado.

Una vez que hayas terminado con los cambios (se applyve bien y estás seguro de que ya no necesitas el alijo), úsalo paragit stash drop deshacerte de él.

Siempre sugiero usar git stash applyen lugar de git stash pop. La diferencia es que applydeja el alijo para volver a intentarlo fácilmente apply, o para verlo, etc. Si poppuede extraer el alijo, también droplo hará inmediatamente, y si posteriormente se da cuenta de que quería extraerlo en otro lugar (en una rama diferente), o con --index, o algo así, eso no es tan fácil. Si es así apply, podrás elegir cuándo hacerlo drop.

Sin embargo, todo es bastante menor de una forma u otra, y para un novato en Git, debería ser más o menos lo mismo. (¡Y puedes saltarte el resto de esto!)


¿Qué pasa si estás haciendo cosas más avanzadas o más complicadas?

Hay al menos tres o cuatro "formas de usar git stash" diferentes, por así decirlo. Lo anterior es para el "camino 1", el "camino fácil":

  1. Comenzaste con una rama limpia, estabas trabajando en algunos cambios y luego te diste cuenta de que los estabas haciendo en la rama equivocada. Sólo desea tomar los cambios que tiene ahora y "moverlos" a otra rama.

Este es el caso fácil, descrito anteriormente. Ejecutar git stash save(o simplemente git stash, lo mismo). Consulte la otra sucursal y use git stash apply. Esto hace que Git se fusione en sus cambios anteriores, utilizando el mecanismo de fusión bastante poderoso de Git. Inspecciona los resultados cuidadosamente (con git diff) para ver si te gustan y, si te gustan, úsalos git stash droppara dejar caer el alijo. ¡Ya terminaste!

  1. Comenzaste algunos cambios y los escondiste. Luego cambiaste a otra rama y comenzaste más cambios, olvidándote de que tenías los guardados.

Ahora desea conservar, o incluso mover, estos cambios y aplicar su alijo también.

De hecho, puedes git stash savevolver a hacerlo, ya que git stashrealiza una "pila" de cambios. Si haces eso, tendrás dos alijos, uno recién llamado stash(pero también puedes escribir stash@{0}) y otro escrito stash@{1}. Úselo git stash list(en cualquier momento) para verlos todos. El más nuevo es siempre el que tiene el número más bajo. Cuando lo haces git stash drop, deja caer el más nuevo y el que estaba stash@{1}se mueve a la parte superior de la pila. Si tuvieras, aún más, el que estaba stash@{2}se convierte en stash@{1}, y así sucesivamente.

Puedes hacerlo applyy luego droptambién un alijo específico: git stash apply stash@{2}, y así sucesivamente. Al soltar un alijo específico, solo se renumeran los que tienen números más altos. De nuevo, el que no tiene número también lo es stash@{0}.

Si acumulas muchos alijos, puede resultar bastante complicado (¿era el alijo que quería stash@{7}o no stash@{4}? Espera, acabo de empujar otro, ¿ahora son 8 y 5?). Personalmente prefiero transferir estos cambios a una nueva rama, porque las ramas tienen nombres y cleanup-attempt-in-Decembersignifican mucho más para mí que stash@{12}. (El git stashcomando toma un mensaje de guardado opcional, y esos pueden ayudar, pero de alguna manera, todos mis alijos terminan con el nombre WIP on branch).

  1. (Extra-avanzado) Ha utilizado git stash save -p, o git addmodificado cuidadosamente y/o git rmmodificado fragmentos específicos de su código antes de ejecutarlo git stash save. Tenía una versión en el índice oculto/área de preparación y otra versión (diferente) en el árbol de trabajo. Quieres preservar todo esto. Entonces ahora usas git stash apply --index, y eso a veces falla con:

    Conflicts in index.  Try without --index.
    
  2. Estás utilizando git stash save --keep-indexpara probar "lo que se comprometerá". Este está más allá del alcance de esta respuesta; vea esta otra respuesta de StackOverflow en su lugar.

Para casos complicados, recomiendo comenzar primero en un árbol de trabajo "limpio", confirmando cualquier cambio que tenga ahora (en una nueva rama si lo desea). De esa manera, el "lugar" donde los estás aplicando no tiene nada más y solo estarás probando los cambios escondidos:

git status               # see if there's anything you need to commit
                         # uh oh, there is - let's put it on a new temp branch
git checkout -b temp     # create new temp branch to save stuff
git add ...              # add (and/or remove) stuff as needed
git commit               # save first set of changes

Ahora estás en un punto de partida "limpio". O tal vez sea más parecido a esto:

git status               # see if there's anything you need to commit
                         # status says "nothing to commit"
git checkout -b temp     # optional: create a new branch for "apply"
git stash apply          # apply stashed changes; see below about --index

Lo principal que hay que recordar es que el "alijo" es una confirmación, es sólo una confirmación ligeramente "divertida/extraña" que no está "en una rama". La applyoperación analiza lo que cambió la confirmación e intenta repetirlo dondequiera que se encuentre ahora. El alijo seguirá ahí ( applylo mantendrá cerca), para que puedas mirarlo más, o decidir que este era el lugar equivocado applyy volver a intentarlo de manera diferente, o lo que sea.


Cada vez que tengas un alijo, puedes usarlo git stash show -ppara ver una versión simplificada de lo que hay en el alijo. (Esta versión simplificada analiza solo los cambios del "árbol de trabajo final", no los cambios de índice guardados que --indexse restauran por separado). El comando git stash apply, sin --index, simplemente intenta realizar esos mismos cambios en su árbol de trabajo ahora.

Esto es cierto incluso si ya tiene algunos cambios. El applycomando se complace en aplicar un alijo a un árbol de trabajo modificado (o al menos, intentar aplicarlo). Puedes, por ejemplo, hacer esto:

git stash apply stash      # apply top of stash stack
git stash apply stash@{1}  # and mix in next stash stack entry too

Puede elegir el orden de "aplicación" aquí, seleccionando reservas particulares para aplicarlas en una secuencia particular. Sin embargo, tenga en cuenta que cada vez que básicamente realiza una "fusión de git", y como advierte la documentación de combinación:

Se desaconseja ejecutar git merge con cambios no triviales no confirmados: si bien es posible, puede dejarlo en un estado del que es difícil salir en caso de un conflicto.

Si comienza con un árbol limpio y solo está realizando varias git applyoperaciones, es fácil retroceder: use git reset --hardpara volver al estado limpio y cambie sus applyoperaciones. (Es por eso que recomiendo comenzar primero con un árbol de trabajo limpio, para estos casos complicados).


¿Qué pasa con el peor de los casos posibles?

Digamos que estás haciendo muchas cosas avanzadas de Git y has creado un alijo y quieres hacerlo git stash apply --index, pero ya no es posible aplicar el alijo guardado --indexporque la rama se ha diversificado demasiado desde el momento en que lo guardaste.

Para esto es git stash branch.

Si usted:

  1. revisa el compromiso exacto en el que estabas cuando hiciste el original stash, luego
  2. crear una nueva rama, y ​​finalmente
  3. git stash apply --index

El intento de recrear los cambios definitivamente funcionará . Esto es lo que hace. (Y luego deja caer el alijo ya que se aplicó con éxito).git stash branch newbranch


Algunas palabras finales sobre --index(¿qué diablos es?)

Lo que --indexhace es simple de explicar, pero un poco complicado internamente:

  • Cuando tenga cambios, debe git addrealizarlos (o "ponerlos en escena") antes de commitrealizar -ing.
  • Por lo tanto, cuando ejecutó git stash, es posible que haya editado ambos archivos fooy zorg, pero solo haya preparado uno de ellos.
  • Entonces, cuando pidas que te devuelvan el alijo, sería bueno que sean git addlas addedcosas y no git add las cosas no agregadas. Es decir, si tiene add-ed foopero no zorgregresó antes de realizar el stash, podría ser bueno tener exactamente la misma configuración. Lo que se escenificó, debería volverse a escenificar; lo que fue modificado pero no escenificado, debe ser nuevamente modificado pero no escenificado.

La --indexbandera applyintenta configurar las cosas de esta manera. Si su árbol de trabajo está limpio, esto generalmente funciona. Sin embargo, si su árbol de trabajo ya tiene cosas add-ed, puede ver cómo podría haber algunos problemas aquí. Si omite --index, la applyoperación no intenta preservar toda la configuración preparada/no preparada. En cambio, simplemente invoca la maquinaria de fusión de Git, utilizando el compromiso del árbol de trabajo en la "bolsa de almacenamiento" . Si no le importa preservar lo que está en escena o no, omitirlo --indexhace que sea mucho más fácil git stash applyhacer lo suyo.

torek avatar Sep 25 '2013 11:09 torek
git stash pop

pondrá todo en su lugar

Como se sugiere en los comentarios, puedes usar git stash branch newbranchpara aplicar el alijo a una nueva rama, que es lo mismo que ejecutar:

git checkout -b newbranch
git stash pop
Stefano Falasca avatar Sep 25 '2013 10:09 Stefano Falasca

To check your stash content :-

git stash list

apply a particular stash no from stash list:-

git stash apply stash@{2}

or for applying just the first stash:-

git stash pop

Note: git stash pop will remove the stash from your stash list whereas git stash apply wont. So use them accordingly.

Shivansh Rajolia - HeLleR avatar Jun 21 '2019 04:06 Shivansh Rajolia - HeLleR