Cómo recuperar cambios ocultos no confirmados
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?
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 diff
para ver el resultado.
Una vez que hayas terminado con los cambios (se apply
ve bien y estás seguro de que ya no necesitas el alijo), úsalo paragit stash drop
deshacerte de él.
Siempre sugiero usar git stash apply
en lugar de git stash pop
. La diferencia es que apply
deja el alijo para volver a intentarlo fácilmente apply
, o para verlo, etc. Si pop
puede extraer el alijo, también drop
lo 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":
- 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 drop
para dejar caer el alijo. ¡Ya terminaste!
- 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 save
volver a hacerlo, ya que git stash
realiza 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 apply
y luego drop
tambié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-December
significan mucho más para mí que stash@{12}
. (El git stash
comando toma un mensaje de guardado opcional, y esos pueden ayudar, pero de alguna manera, todos mis alijos terminan con el nombre WIP on branch
).
(Extra-avanzado) Ha utilizado
git stash save -p
, ogit add
modificado cuidadosamente y/ogit rm
modificado fragmentos específicos de su código antes de ejecutarlogit 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 usasgit stash apply --index
, y eso a veces falla con:Conflicts in index. Try without --index.
Estás utilizando
git stash save --keep-index
para 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 apply
operación analiza lo que cambió la confirmación e intenta repetirlo dondequiera que se encuentre ahora. El alijo seguirá ahí ( apply
lo mantendrá cerca), para que puedas mirarlo más, o decidir que este era el lugar equivocado apply
y volver a intentarlo de manera diferente, o lo que sea.
Cada vez que tengas un alijo, puedes usarlo git stash show -p
para 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 --index
se 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 apply
comando 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 apply
operaciones, es fácil retroceder: use git reset --hard
para volver al estado limpio y cambie sus apply
operaciones. (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 --index
porque la rama se ha diversificado demasiado desde el momento en que lo guardaste.
Para esto es git stash branch
.
Si usted:
- revisa el compromiso exacto en el que estabas cuando hiciste el original
stash
, luego - crear una nueva rama, y finalmente
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 --index
hace es simple de explicar, pero un poco complicado internamente:
- Cuando tenga cambios, debe
git add
realizarlos (o "ponerlos en escena") antes decommit
realizar -ing. - Por lo tanto, cuando ejecutó
git stash
, es posible que haya editado ambos archivosfoo
yzorg
, pero solo haya preparado uno de ellos. - Entonces, cuando pidas que te devuelvan el alijo, sería bueno que sean
git add
lasadded
cosas y nogit add
las cosas no agregadas. Es decir, si tieneadd
-edfoo
pero nozorg
regresó antes de realizar elstash
, 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 --index
bandera apply
intenta 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 apply
operació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 --index
hace que sea mucho más fácil git stash apply
hacer lo suyo.
git stash pop
pondrá todo en su lugar
Como se sugiere en los comentarios, puedes usar git stash branch newbranch
para aplicar el alijo a una nueva rama, que es lo mismo que ejecutar:
git checkout -b newbranch
git stash pop
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.