git-stash frente a git-branch

92

En una pregunta anterior de Git , Daniel Benamy estaba hablando de un flujo de trabajo en Git:

Estaba trabajando en master y comprometí algunas cosas y luego decidí que quería dejar ese trabajo en espera. Hice una copia de seguridad de algunas confirmaciones y luego me ramifiqué antes de comenzar mi trabajo de mierda.

Quería restaurar su estado de trabajo a un punto anterior en el tiempo sin perder sus cambios actuales. Todas las respuestas giraban en torno, de diversas formas, a algo como

git branch -m master crap_work
git branch -m previous_master master

¿Cómo se compara esto con git stash? Estoy un poco confundido tratando de ver cuál es el caso de uso diferente aquí cuando parece que todo git stashya se maneja mediante la ramificación ...


@ Jordi Bunster : Gracias, eso aclara las cosas. Supongo que consideraría "escondite" como una rama ligera y sin nombre. Entonces, cualquier cosa que pueda hacer el alijo, la rama también puede hacerlo, pero con más palabras. ¡Agradable!

Will Robertson
fuente

Respuestas:

109

'alijo' toma lo no comprometido, " sucio cosas " en su copia de trabajo y las guarda, dejándolo con una copia de trabajo limpia.

Realmente no se ramifica en absoluto. Luego puede aplicar el alijo sobre cualquier otra rama. O, a partir de Git 1.6, puede hacer:

git stash branch <branchname> [<stash>]

para aplicar el alijo en la parte superior de una nueva rama, todo en un comando.

Por lo tanto, el alijo funciona muy bien si aún no se ha comprometido con la rama " incorrecta ".

Si ya se comprometió, entonces el flujo de trabajo que describe en su pregunta es una mejor alternativa. Y, por cierto, tienes razón: Git es muy flexible y con esa flexibilidad viene la funcionalidad superpuesta.

Jordi Bunster
fuente
1
una cosa que me muerde ... ¿puedes escribir cómo se ve realmente un [<stash>]? Lo pusieron en esa notación en los documentos, pero no es obvio si debería ser 1 o @ {1} o qué.
Gregg Lind
1
Si quieres hacer referencia a un alijo específico "N", usa alijo @ {N}
Jordi Bunster
9
Consulta git stash listlos nombres de tus alijos.
idbrii
6
Gregg, sí, puedes: git stash save (nombre de tu alijo). Lo hace mucho más útil si lo usa mucho para que sepa lo que hace cada alijo. Puedes usar git stash show -p (nombre) para mostrarte el parche de un alijo.
Thomas Vander Stichele
7
también, git stash show -upara mostrar una diferencia del alijo contra la copia de trabajo.
ken
49

Cuando restaura su alijo, sus cambios se vuelven a aplicar y continúa trabajando en su código.

Para esconder sus cambios actuales

$ git stash save 
Saved "WIP on master: e71813e..."

También puede tener más de un alijo. El alijo funciona como una pila. Cada vez que guarde un nuevo alijo, se coloca en la parte superior de la pila.

$ git stash list
stash@{0}: WIP on master: e71813e..."

Nota la stash@{0} parte? Esa es tu identificación de alijo. Lo necesitará para restaurarlo más adelante. Hagámoslo ahora mismo. El ID de alijo cambia con cada alijo que hagas. alijo @ {0} se refiere al último alijo que hiciste.

Para aplicar un alijo

$ git stash apply stash@{0}

Puede notar que el alijo todavía está allí después de haberlo aplicado. Puede dejarlo si ya no lo necesita.

$ git stash drop stash@{0}

O, debido a que el alijo actúa como una pila, puede sacar el último alijo que guardó:

$ git stash pop

Si desea borrar todas sus reservas, ejecute el comando 'borrar':

$ git stash clear

Es muy posible que no uses escondites con tanta frecuencia. Si solo desea guardar rápidamente sus cambios para restaurarlos más tarde, puede omitir el ID de alijo.

$ git stash
...
$ git stash pop

Siéntete libre de experimentar con el alijo antes de usarlo en un trabajo realmente importante.

También tengo una versión más detallada de esto publicada en mi blog .

Ariejan
fuente
un recurso mucho más útil que la supuesta 'mejor' respuesta ... (aunque la mejor respuesta lo dejó muy claro, hubo algunas confusiones relacionadas con el uso completo)
kumarharsh
9

Siempre desconfío de los git stash. Si lo esconde varias veces, las cosas tienden a complicarse. La lista de escondites de git mostrará una lista numerada de los escondites que creaste, con mensajes si los proporcionaste ... Pero el problema radica en el hecho de que no puedes limpiar los escondites excepto con un brutal git stash clear (que los elimina a todos) . Entonces, a menos que siempre seas anal al dar mensajes superdescriptivos para tus alijos (un poco va en contra de la filosofía del alijo), terminas con un montón incomprensible de alijos.

La única forma que conozco de averiguar cuál es cuál es usar gitk, todo y detectar los alijos. Al menos esto le permite ver en qué se creó el alijo, así como la diferencia de todo lo que se incluye en ese alijo.

Tenga en cuenta que estoy usando git 1.5.4.3, y creo que 1.6 agrega git stash pop, que supongo que aplicaría el alijo seleccionado y eliminaría de la lista. Lo que parece mucho más limpio.

Por ahora, siempre trato de bifurcarme a menos que esté absolutamente seguro de que volveré a ese escondite el mismo día, incluso dentro de una hora.

webmat
fuente
3
¿Haces ramas sin darles nombres útiles? Si no, no veo por qué no haces lo mismo con el alijo. Si realmente desea saber qué contienen, simplemente use git-stash show para mostrar qué archivos cambiaron, o git-stash apply y git-diff para ver las diferencias reales. Mantener el alijo recortado es lo mismo que mantener las ramas bajo control.
Xiong Chiamiov
18
en realidad, puede eliminar un solo alijo usandogit stash drop [<stash>]
kumarharsh
1
Es cierto que git ha tenido git stash drop durante mucho tiempo. Es mucho menos un PITA para usar ahora. Lo uso todos los días, e incluso durante largos períodos de tiempo, ahora.
webmat
3

Si busca un flujo de trabajo que pueda ser más adecuado que git stash, es posible que desee mirar git-bottle . Es una utilidad con el propósito de guardar y restaurar los diversos estados de trabajo de git como confirmaciones de git normales, capturando de manera efectiva el estado actual y pertinente de su árbol de trabajo y todos los estados de archivo que se muestran en el estado de git.

Diferencias clave de git stash:

  • git stashguarda el estado sucio de git de forma limitada (archivos modificados y archivos agregados en el índice), mientras que git-bottleestá diseñado para guardar todo lo que es diferente de HEAD, y diferencia de una manera preservadora entre rutas modificadas, modificadas y no agregadas, no agregadas, no fusionadas, y los estados completos de rebase / merge (solo las rutas debajo .gitignoreno se guardan).
  • git stashguarda para esconder los objetos que necesita para realizar un seguimiento por separado. Si escondí algo hace 2 semanas, es posible que no lo recuerde, mientras que se git-bottleguarda como confirmaciones tentativas en la rama actual . La acción inversa es la git-unbottleque equivale al git stashpop. Es posible enviar y compartir estas confirmaciones entre repositorios. Esto puede ser útil para compilaciones remotas, donde tiene otro repositorio en un servidor remoto solo para compilar o para colaborar con otras personas en la resolución de conflictos.
Dan Aloni
fuente