¿Cuál es el caso de uso previsto para git stash?

143

Si trabajo en la rama A y de repente necesito trabajar en la rama B antes de estar listo con una confirmación en la rama A, guardo mis cambios en A, pago B, hago mi trabajo allí, luego pago A y aplico el alijo.

Si trabajo en A y quiero dejar de trabajar por el día, ¿debo guardar mi trabajo y luego aplicarlo al día siguiente (cuando reanude mi trabajo), o debo dejar las cosas como están: archivos modificados sin confirmar en el ¿directorio de trabajo? No veo por qué necesitaría usar alijo en este caso, excepto si hay algún beneficio de seguridad.

Además, otro escenario: trabajo tanto en el trabajo como en casa. Si no estoy listo con un compromiso cuando quiero ir a casa, ¿puedo guardar mi trabajo, enviarlo a GitHub y luego sacar ese alijo en casa?

Alejandro
fuente
3
depende en gran medida de las políticas de su empresa, si las hay. ¿Cómo elegirá la respuesta "aceptada"?
Daemon Painter
1
Esta pregunta tal como está formulada es solo para pedir opiniones (¿debo usar git de esta manera o de esa manera?) Y, por lo tanto, debe cerrarse o editarse.
TylerH

Respuestas:

161

Stash es solo un método de conveniencia. Dado que las ramas son tan baratas y fáciles de administrar en git, yo personalmente casi siempre prefiero crear una nueva rama temporal que guardarla, pero es una cuestión de gustos principalmente.

El único lugar que me gusta guardar es si descubro que olvidé algo en mi última confirmación y ya comencé a trabajar en la siguiente en la misma rama:

# Assume the latest commit was already done
# start working on the next patch, and discovered I was missing something

# stash away the current mess I made
git stash save

# some changes in the working dir

# and now add them to the last commit:
git add -u
git commit --amend

# back to work!
git stash pop
Mureinik
fuente
2
¿Lo que agregaste que faltaba se fusiona con el alijo una vez que lo quitas? (Todavía tengo dudas sobre cómo funciona la línea de tiempo en git, ¿supongo que está sobrescribiendo el historial?)
Kiki Jewell
Los cambios emergentes de @KikiJewell se aplican en el índice, no se confirman. así que si lo hace git stash popdos veces, perderá la distinción entre esos dos conjuntos de cambios.
Mureinik
A finales de octubre de 2017, ha habido una amplia discusión sobre la lista de correo de Git, en la que el comando git stash save está siendo obsoleto en favor de la alternativa existente git stash push. La razón principal de esto es que git stash pushintroduce la opción de ocultar las especificaciones de ruta seleccionadas , algo que git stash saveno es compatible.
Krishna Gupta
39

Romperé la respuesta en tres párrafos.

Parte 1:

git stash(Para guardar los cambios no confirmados en un "alijo". Nota: ¡ esto elimina los cambios del árbol de trabajo!)

git checkout some_branch(cambiar a la rama prevista, en este caso some_branch)

git stash list (lista de escondites)

Puede ver:
stash @ {0}: WIP en {branch_name}: {SHA-1 of last commit} {last commit of you branch}
stash @ {0}: WIP on master: modificación 085b095c6 para prueba

git stash apply (aplicar alijo al árbol de trabajo en la rama actual)

git stash apply stash@{12}(si tiene muchos alijo, puede elegir qué alijo se aplicará; en este caso, aplicamos alijo 12)

git stash drop stash@{0}(para eliminar de la lista de alijo - en este caso alijo 0)

git stash pop stash@{1} (para aplicar el alijo seleccionado y soltarlo de la lista de alijo)

Parte 2:
Puede ocultar sus cambios con este comando, pero no es necesario.
Puede continuar al día siguiente sin alijo.
¡Estos comandos para ocultar sus cambios y trabajar en diferentes ramas o para implementar alguna realización de su código y guardar en alijos sin ramas y confirmar su caso personalizado!
Y luego puedes usar algunos de los alijos y comprobar cuál es mejor.

Parte 3:
comando Stash para ocultar localmente sus cambios.
Si desea trabajar de forma remota, debe comprometerse y presionar.

Alexander Yushko
fuente
10

La idea principal es

Guarde los cambios en un directorio de trabajo sucio

Por lo tanto, el comando Básicamente Stash conserva algunos cambios que no los necesita o los quiere en este momento; pero puede que los necesite.

Utilice git stash cuando desee registrar el estado actual del directorio de trabajo y el índice, pero desea volver a un directorio de trabajo limpio. El comando guarda sus modificaciones locales y revierte el directorio de trabajo para que coincida con la confirmación HEAD .

nzrytmn
fuente
7

Puede utilizar los siguientes comandos:

  • Para guardar sus cambios no confirmados

    git stash

  • Para enumerar sus alijos guardados

    git stash list

  • Para aplicar / recuperar los cambios no comprometidos donde x es 0,1,2 ...

    git stash apply stash@{x}

Nota:

  • Para aplicar un alijo y eliminarlo de la lista de alijo

    git stash pop stash@{x}

  • Para aplicar un alijo y mantenerlo en la lista de alijo

    git stash apply stash@{x}

Anushil Kumar
fuente
4

Si presiona git stashcuando tiene cambios en la copia de trabajo (no en el área de preparación), git creará un objeto escondido y lo empujará a la pila de alijo (como lo hizo, git checkout -- .pero no perderá los cambios). Más tarde, puede aparecer desde la parte superior de la pila.

Gyorgyabraham
fuente
2

El comando stash ocultará cualquier cambio que haya realizado desde su última confirmación. En su caso, no hay razón para guardarlo si continuará trabajando en él al día siguiente. Solo usaría alijo para deshacer los cambios que no desea confirmar.

Severin
fuente
2
No, git stashno cambiará de rama. Especialmente no "revertirá" ningún cambio comprometido. Solo descartará (temporalmente) cualquier cambio no confirmado en sus archivos. - Puede parecer exigente, pero ese tipo de palabras tienen un significado muy especial en el contexto de git. Realmente no deberías mezclarlos.
michas
Gracias por señalar eso. Cambié mi respuesta en consecuencia.
Severin
En git, una "rama" se define como una serie de confirmaciones. git stashno tocará ninguna confirmación y por lo tanto no modificará ninguna rama en absoluto. No "eliminará" nada de una rama y no lo "restablecerá" de ninguna manera. La rama permanece igual, solo cambian los archivos en el árbol de trabajo. - Esas son dos cosas totalmente distintas.
michas
¡No descartará, sino que "guardará" los cambios! Git mantiene una estructura LIFO para escondites, por lo que un alijo es en realidad un empujón y puede aparecer desde la parte superior. La palabra "descartar" significa que perderá cualquier cosa, pero no lo hará.
gyorgyabraham
2

Sé que StackOverflow no es el lugar para respuestas basadas en opiniones, pero en realidad tengo una buena opinión sobre cuándo dejar de lado los cambios con un alijo.

No quieres comprometerte con cambios experimentales

Cuando realiza cambios en su espacio de trabajo / árbol de trabajo, si necesita realizar operaciones basadas en ramas como fusionar, empujar, recuperar o extraer, debe estar en un punto de confirmación limpio. Entonces, si tiene cambios en el espacio de trabajo, debe confirmarlos. Pero, ¿y si no quieres cometerlos? ¿Y si son experimentales? ¿Algo que no quieres que forme parte de tu historial de confirmaciones? ¿Algo que no desea que otros vean cuando ingrese a GitHub?

No quiere perder los cambios locales con un restablecimiento completo

En ese caso, puede hacer un restablecimiento completo. Pero si realiza un restablecimiento completo, perderá todos los cambios de su árbol de trabajo local porque todo se sobrescribe en el lugar donde estaba en el momento de la última confirmación y perderá todos sus cambios.

Entonces, en cuanto a la respuesta de 'cuándo debería esconder', la respuesta es cuando necesita volver a un punto de compromiso limpio con un árbol de trabajo / índice / compromiso sincronizado, pero no quiere perder sus cambios locales en el proceso. Simplemente guarde sus cambios en un escondite y estará bien.

Y una vez que haya hecho su alijo y luego se haya fusionado, tirado o empujado, puede simplemente guardar pop o aplicar y volverá al punto de partida.

Git alijo y GitHub

GitHub agrega constantemente nuevas funciones, pero a partir de ahora, ahora hay una forma de guardar un alijo allí. Nuevamente, la idea de un escondite es que sea local y privado. Nadie más puede echar un vistazo a su escondite sin acceso físico a su estación de trabajo. De la misma manera que git reflog es privado con git log es público. Probablemente no sería privado si se subiera a GitHub.

Un truco podría ser hacer una diferencia de su espacio de trabajo, verificar la diferencia en su repositorio de git, confirmar y luego presionar. Luego puede hacer un tirón desde casa, obtener el diferencial y luego desenrollarlo. Pero esa es una forma bastante complicada de lograr esos resultados.

git diff > git-dif-file.diff

abre el alijo

Cameron McKenzie
fuente