2010-04-02 10 views
742

Contexto: estoy trabajando en el maestro 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 sucursal.Git: crea una bifurcación desde cambios no asignados/no confirmados en el maestro

Esto siempre me pasa y no tengo ni idea de cómo cambiar a otra rama y tomar todos estos cambios sin compromiso conmigo dejando la rama principal limpia. git stash && git stash branch new_branch supone que simplemente lograr eso, pero esto es lo que me pasa:

~/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/[email protected]{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") 

¿Conoce si hay alguna manera de lograr esto?

+0

Aunque no existe una solución más sencilla a su problema, ¿podría especificar en lo que el resultado que se obtiene difiere de lo que quería? – Gauthier

+1

haciendo lo anterior o las respuestas en la parte inferior, los cambios sin compromiso están tanto en el maestro como en la nueva rama. Los quiero solo en la nueva sucursal, así que puedo pagar master y trabajar en otra cosa sin tener estos cambios flotando alrededor de – knoopx

+1

ver mi respuesta editada. Debe confirmar los cambios locales en la nueva sucursal si desea pagar un master limpio. Los cambios locales son solo las diferencias entre el HEAD actual y sus archivos en el disco. Estos cambios en los archivos locales no están versionados, debe indicarle a git que los guarde en algún lugar si desea recuperarlos más adelante. – Gauthier

Respuesta

884

No hay necesidad de esconder.

git checkout -b new_branch_name 

no toca los cambios locales. Simplemente crea la rama de la CABEZA actual y establece 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 descartar los cambios?

Como los cambios son solo locales, git no quiere que los pierda demasiado fácilmente. Al cambiar de rama, git no sobrescribe sus cambios locales. 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ó sus archivos locales. Es por eso que su último estado aún muestra sus cambios locales, aunque se encuentre en el master.

Si realmente desea descartar los cambios locales, debe forzar la salida con -f.

git checkout master -f 

Dado que los cambios nunca se cometieron, los perdería.

Trate de volver a su sucursal, confirme sus cambios y vuelva a consultar el maestro.

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

Debe obtener un mensaje M después de la primera salida, pero entonces ya no más después de la checkout master y git status no debe mostrar los archivos modificados.

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

de trabajo En respuesta a su primer comentario, los cambios locales son sólo ... bueno, local. Git no los guarda automáticamente, debes decirle que los guarde para más adelante. Si realiza cambios y no los compromete o oculta explícitamente, git no los versionará. Si cambia HEAD (checkout master), los cambios locales no se sobrescribirán porque no se guardaron.

+0

Así es como siempre lo hago. Funciona exactamente como te gustaría. – synic

+0

amigo, me estaba perdiendo este punto importante. Creo que entendí por qué sucede esto y por qué obviamente Git no puede ignorar los cambios (sin forzar el descarte) si no los cometo primero. Gracias: D – knoopx

+22

Lo confuso aquí es que la página man de git indica que 'git checkout'" actualiza los archivos en el árbol de trabajo para que coincida con la versión en el índice o el árbol especificado. ". Eso supone que los cambios en su sistema de archivos serán * GONE * después. Sin ninguna posibilidad de recuperarlos. Incluso si dices que no lo harán, esto deja una muy mala sensación. No confío en esto * en absoluto *. O la documentación es realmente mala o el comportamiento predeterminado de git es realmente peligroso. Uno no debería tener que confiar en alguna heurística "automática" para detectar que en este caso no quiere perder sus cambios. – Evi1M4chine

46

Probar:

git stash 
git checkout -b new-branch 
git stash apply 
+5

¿Es esto diferente a simplemente hacer 'git checkout -b new-branch' por sí mismo? –

+0

No creo que fue cuando la respuesta fue escrita originalmente, pero podría estar equivocado. Desafortunadamente, debido a mi circunstancia laboral, he estado utilizando forzosamente los últimos años, por lo que no puedo dar fe de su precisión ahora. –

+2

O en lugar de los dos últimos pasos: git stash branch new-branch – rethab

12

dos cosas que puede hacer:

git stash -u 
git branch sillyname [email protected]{0} 

o

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

(git stash -u < - la -u significa que también se necesita cambios unstaged)

(git checkout - < - la dash es un atajo para la rama anterior en la que estaba)

4

Si está utilizando el cliente GitHub Windows (como yo) y está en la situación de haber realizado cambios no confirmados que desea mover a una nueva rama, simplemente puede "Crate una nueva rama" a través del cliente GitHub . Cambiará a la rama recién creada y conservará sus cambios.

enter image description here

+0

que guarda los cambios antes de crear la nueva rama para que no los guarde (versión 223 en Mac OS) –

Cuestiones relacionadas