¿Git Stash es específico de la rama o para todo el repositorio?

95

Entré en una sucursal e hice algunos trabajos. Quería ir a otra rama pero no quería comprometerme, así que lo hice git stash. Entonces lo hice git checkout <otherbranch>. Hice un trabajo allí y, al igual que en la primera rama, quería cambiar antes de realizar el trabajo. Así que yo también lo hice git stashallí. Volví a la primera rama y traté de deshacerla ( git stash pop) pensando que obtendría el alijo de esa rama específica. Me sorprendió que sacara el alijo de <otherbranch>(último escondido). Tenía la impresión de que el alijo es específico de la rama, pero este comportamiento indica que solo hay un alijo para todo el repositorio local.

¿Es git stashespecífico de la rama o para todo el repositorio? Si es para todo el repositorio, ¿puedo pasarle opciones para que sea específico de la rama?

anfibio
fuente

Respuestas:

43

Para ver la pila de alijo actual:

git stash list

Para elegir un alijo específico de la pila, consúltelo como se muestra arriba.stash@{number}

Si desea que el comportamiento sea por rama, puede realizar una confirmación (o varias confirmaciones) en la rama. Siempre puede "deshacer" las confirmaciones más tarde (por ejemplo, con git reset, --softo --mixed; vea la documentación de git reset ; o con git rebase -ipara mantener solo las eventuales confirmaciones "reales" mientras se descartan los temporales).

(Para emular realmente git stash, necesita al menos dos confirmaciones, una para el estado del índice y otra para el estado del árbol de trabajo. Sin embargo, si no planea guardar y restaurar el estado del índice, puede solo git add -Ael estado del árbol de trabajo completo y poner eso en la confirmación temporal. Alternativamente, git stashes un script de shell para que pueda copiarlo y modificarlo con bastante facilidad para que funcione por rama de forma predeterminada, usando, por ejemplo, como su espacio de nombre de trabajo, en lugar del único global para el repositorio completo. Aún podría llevar un alijo de una rama a otra nombrándolo explícitamente).refs/pb-stash/branchrefs/stash

torek
fuente
¿Sabe cómo mostrar la lista de archivos de cada stash listelemento además de una descripción?
anfibio
2
git stash show(o git stash show stash@{<number>}para algo diferente a la @{0}versión) le da un diff --stat; agregue -ppara obtener una diferencia mayor. Nota: esto compara el "árbol de trabajo" en la "bolsa de alijo" con el compromiso del que cuelga; no hay una interfaz frontal para ver qué hay en el "índice" en la bolsa de almacenamiento dada.
torek
55

No y No. git stash es por repositorio.

Aquí hay una buena página sobre cómo usarlo.

abasterfield
fuente
¿El segundo alijo sobrescribe al primero? IOW, si hago dos alijos pero no desecho en el medio, ¿pierdo el primer alijo?
anfibio
1
No, obtienes una pila (último en entrar, primero en salir) de escondites. Se presiona un alijo de su escondite-pila, y luego otro y luego que el pop a cabo la segunda a continuación, que el pop a cabo la primera, etc.
abasterfield
18

git stash no es por rama.

  • En lugar de git stash(que se puede perder fácilmente cuando tienes muchos escondites y ramas)
  • Sugiero hacer una git commitpara guardar el código sin terminar en su rama y cuando esté listo para terminar el código, haga una git reset ${COMMIT_HASH_VALUE}para recuperar el código sin terminar.
  • git commity git resetcuando se usan juntos correctamente pueden simular un git stashpara una rama específica

A continuación, se muestra un escenario común de la vida real que demuestra el valor y el uso de los comandos commity reset:

  • está trabajando en la rama de funciones X y su código ni siquiera compila o pasa las pruebas
  • hay un error que tiene mayor prioridad que la nueva característica actual y, por lo tanto, debe comenzar a trabajar de inmediato en la corrección del error
  • en lugar de hacer un git alijo (y el alijo se pierde en la mezcla porque tienes muchos alijos y muchas ramas)
  • puedes hacer una git commitfunción en la rama X
    • escribe el COMMIT_HASH_VALUEpara más tarde
  • revisa una nueva rama Y para la corrección urgente
  • finalice el hotfix en la rama Y (realice una solicitud de fusión para obtener el hotfix en la línea de base y eliminar la rama de hotfix)
  • luego revisa la rama de características X nuevamente
  • para hacer estallar su trabajo inacabado que no se compiló o pasó la prueba -> simplemente haga un git reset ${COMMIT_HASH_VALUE}

(Para su información, el valor predeterminado git resetes --mixed)

Trevor Boyd Smith
fuente
2
Un atajo útil para restablecer en este escenario es git reset HEAD~1.
Sam A. Horvath-Hunt
1
@samHH he tenido demasiadas instancias con git reset HEAD ^ 1 accidentalmente golpeado dos veces ... así que elijo no usar HEAD^1o HEAD~1.
Trevor Boyd Smith
11

No estoy seguro de por qué todas las respuestas aquí sugieren emular el alijo con commit+ reset. Stash está perfectamente bien de usar, especialmente cuando se trabaja en varias ramas. Tampoco quiero comprometerme cuando trabajo en varias ramas, porque quiero que todos los cambios modificados estén resaltados en mi editor cuando regrese.

Así que aquí está el flujo de trabajo de alijo:

Siempre que tenga que cambiar de rama y no esté listo para comprometerse, guarde sus cambios en la pila

git stash save "Your custom stash message"

Cuando regrese a una sucursal, revise el alijo

git stash list

ingrese la descripción de la imagen aquí

Si está en la rama FixIssue0203, podría usar el uso git stash popporque esto aplicará la parte superior stash@{0}y la eliminará del escondite.

Sin embargo, si está en la rama ImproveReadme, primero debe aplicar el alijo 1 git stash apply stash@{1}y luego quitar el alijo 1 de la pila git stash drop stash@{1}.

¡Eso es!

Adán
fuente