git switch branch sin descartar cambios locales

182

Muy bien, digamos que un día hacemos un montón de modificaciones y cuando vamos a confirmarlas, notamos que estábamos trabajando en la rama equivocada.

¿Cómo podemos forzar a git a cambiar de rama sin descartar los cambios locales ?

Probablemente voy a hacer esto de una manera ingenua mientras espero una respuesta, pero me gustaría saber si hay un procedimiento correcto ya que estaría mintiendo si dijera que esto no me ha sucedido antes ...

  • Copia de seguridad cambiada repos
  • git reset --hard
  • git checkout right-branch
  • Restaurar cambios
  • git commit -m "changes"
megawac
fuente

Respuestas:

343

Hay un montón de formas diferentes dependiendo de qué tan avanzado esté y en qué rama (s) las quiere.

Tomemos un error clásico:

$ git checkout master
... pause for coffee, etc ...
... return, edit a bunch of stuff, then: oops, wanted to be on develop

Así que ahora desea que estos cambios, los cuales aún no se han comprometido a master, para estar en develop.

  1. Si aún no tiene uno develop, el método es trivial:

    $ git checkout -b develop
    

    Esto crea una nueva developrama a partir de donde sea que esté ahora. Ahora puedes comprometerte y todo lo nuevo está listo develop.

  2. Usted tienen una develop. Vea si Git le permitirá cambiar sin hacer nada:

    $ git checkout develop
    

    Esto tendrá éxito o se quejará. Si tiene éxito, ¡genial! Solo comprométete. Si no ( error: Your local changes to the following files would be overwritten ...), todavía tiene muchas opciones.

    La más fácil es probablemente git stash(como postdijeron todos los otros contestadores que me ganaron a hacer clic ). Ejecutar git stash saveo git stash push, 1 o simplemente, git stashque es la abreviatura desave / push:

    $ git stash
    

    Esto confirma su código (sí, realmente realiza algunas confirmaciones) utilizando un método extraño que no es de ramificación. Las confirmaciones que realiza no están "en" ninguna rama, sino que ahora se almacenan de forma segura en el repositorio, por lo que ahora puede cambiar de rama y luego "aplicar" el alijo:

    $ git checkout develop
    Switched to branch 'develop'
    $ git stash apply
    

    Si todo va bien y le gustan los resultados, entonces debería git stash drop guardarlos. Esto elimina la referencia a los extraños commits no-branch-y. (Todavía están en el repositorio, y a veces se pueden recuperar en una emergencia, pero para la mayoría de los propósitos, debe considerar que desaparecieron en ese momento).

El applypaso fusiona los cambios escondidos, utilizando la poderosa maquinaria de fusión subyacente de Git, el mismo tipo de cosas que utiliza cuando realiza fusiones de ramas. Esto significa que puede obtener "conflictos de fusión" si la rama en la que estaba trabajando por error es lo suficientemente diferente de la rama en la que desea trabajar. Por lo tanto, es una buena idea inspeccionar los resultados cuidadosamente antes de asumir que el alijo se aplicó limpiamente, incluso si Git no detectó ningún conflicto de fusión.

Mucha gente usa git stash pop, que es abreviatura para git stash apply && git stash drop. Eso está bien en lo que respecta, pero significa que si la aplicación resulta en un desastre y decides que no quieres seguir por este camino, no puedes recuperar el alijo fácilmente. Es por eso que recomiendo por separado apply, inspeccionar los resultados, dropsolo si / cuando esté satisfecho. (Por supuesto, esto introduce otro punto en el que puede tomar otro descanso para tomar un café y olvidar lo que estaba haciendo, regresar y hacer lo incorrecto , por lo que no es una cura perfecta).


1 El savein git stash savees el antiguo verbo para crear un nuevo alijo. La versión 2.13 de Git introdujo el nuevo verbo para hacer las cosas más consistentes popy para agregar más opciones al comando de creación. La versión 2.16 de Git desaprobó formalmente el verbo antiguo (aunque todavía funciona en Git 2.23, que es la última versión en el momento en que estoy editando esto).

torek
fuente
3
¿Qué sucede si deseo cambiar a otra rama sin comprometerme con la rama actual (por ejemplo, los cambios no están terminados) y luego volver a continuar?
stt106
@ stt106: aún debe comprometerse, pero puede hacerlo, como en esta y las otras respuestas, a través de git stashmodo que las confirmaciones git stash, ya que obtiene dos confirmaciones por entrada de escondite, en un arreglo inusual, no se encuentran en ninguna rama. Sin embargo, excepto en casos especiales a muy corto plazo, generalmente prefiero hacer una confirmación normal. Puede git reset --softo git reset --mixedmás tarde, o usar git commit --amendpara dejarlo de lado, cuando vuelva a trabajar en esa rama. (En Git moderno, también puede usar git worktree add, que puede ser una solución aún mejor.)
torek
"Esto tendrá éxito o se quejará". ¿Cuáles serían las razones del éxito o error al hacer el pago?
nanocv
1
@nanocv: consulte stackoverflow.com/questions/22053757/…
torek el
todos mis cambios locales se pierden cuando cambio con los pasos anteriores, estoy en <a> rama y hago mis cambios y quiero moverme a <b> rama y empujar todos mis cambios en eso. cuando estoy haciendo git stash y moviéndome a otras ramas, estoy sacando todos los archivos de la rama <b> y mis cambios locales se están perdiendo
Mukul Munjal
38

Usa git stash

git stash

Empuja los cambios a una pila. Cuando quiera retirarlos, use

 git stash apply

Incluso puede sacar elementos individuales. Para volar por completo el alijo:

 git stash clear
Rayo
fuente
77
El último comando probablemente debería ser git stash drop; git stash cleareliminará toda la pila de alijo, incluidas las alijas posiblemente no relacionadas con este conjunto de comandos.
Leland
15
  • git stash para guardar sus cambios no confirmados
  • git stash list para enumerar sus reservas no comprometidas guardadas
  • git stash apply stash@{x} donde x puede ser 0,1,2..no de escondites que hayas hecho
pie roto
fuente
4

Tu también puedes :

  • Úselo git stashpara archivar sus cambios o,

  • Cree otra rama y confirme sus cambios allí, y luego combine esa rama en su directorio de trabajo

X3074861X
fuente