Git: Crear una rama a partir de cambios no editados / no confirmados en master


Contexto: Estoy trabajando en master agregando una característica simple. Después de unos minutos me di cuenta de que no era tan simple y que debería haber sido mejor trabajar en una nueva rama.

Esto siempre me sucede y no tengo idea de cómo cambiar a otra rama y tomar todos estos cambios no comprometidos conmigo dejando la rama maestra limpia. Supuse que git stash && git stash branch new_branch simplemente lograría eso, pero esto es lo que obtengo:

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ echo "hello!" > testing 

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git stash
Saved working directory and index state WIP on master: 4402b8c testing
HEAD is now at 4402b8c testing

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ git stash branch new_branch
Switched to a new branch 'new_branch'
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (db1b9a3391a82d86c9fdd26dab095ba9b820e35b)

~/test $ git s
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git checkout master
M   testing
Switched to branch 'master'

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

¿Sabes si hay alguna manera de lograr esto?

 810
Author: Cœur, 2010-04-03

4 answers

No hay necesidad de guardar.

git checkout -b new_branch_name

No toca los cambios locales. Simplemente crea la rama de la CABEZA actual y coloca la CABEZA allí. Así que supongo que eso es lo que quieres.

--- Editar para explicar el resultado de checkout master ---

¿Estás confundido porque checkout master no descarta tus cambios?

Dado que los cambios son solo locales, git no quiere que los pierdas con demasiada facilidad. Al cambiar de rama, git no sobrescribe su local cambio. El resultado de su checkout master es:

M   testing

, lo que significa que sus archivos de trabajo no están limpios. git cambió el HEAD, pero no sobrescribió tus archivos locales. Es por eso que su último estado aún muestra sus cambios locales, aunque esté en master.

Si realmente quieres descartar los cambios locales, tienes que forzar el checkout con -f.

git checkout master -f

Dado que tus cambios nunca fueron confirmados, los perderías.

Intenta volver a tu rama, confirmar sus cambios, luego revise el maestro de nuevo.

git checkout new_branch
git commit -a -m"edited"
git checkout master
git status

Debe recibir un mensaje M después del primer checkout, pero luego no más después de checkout master, y git status no debe mostrar ningún archivo modificado.

--- Editar para aclarar la confusión sobre el directorio de trabajo (archivos locales)---

En respuesta a su primer comentario, los cambios locales son justos... bueno, local. Git no los guarda automáticamente, debes decirle que los guarde para más tarde. Si realiza cambios y no lo hace explícitamente commit o stash ellos, git no va a versionarlos. Si cambia HEAD (checkout master), los cambios locales no se sobrescriben desde no guardados.

 969
Author: Gauthier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-02 23:14:09

Intenta:

git stash
git checkout -b new-branch
git stash apply
 52
Author: Grant Limberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-02 22:15:12

Dos cosas que puedes hacer:

git checkout -b sillyname
git commit -am "silly message"
git checkout - 

O

git stash -u
git branch sillyname stash@{0}

(git checkout -

(git stash -u -u significa que también toma cambios no escalonados)

 15
Author: Pylinux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-14 09:12:18

Si estás usando el cliente de Windows de GitHub (como yo) y estás en la situación de haber hecho cambios sin confirmar que deseas mover a una nueva rama, simplemente puedes "Crear una nueva rama" a través del cliente de GitHub. Cambiará a la rama recién creada y conservará sus cambios.

introduzca la descripción de la imagen aquí

 4
Author: Tod Birdsall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-17 15:29:17