git: cambie de rama e ignore cualquier cambio sin comprometerse


318

Estaba trabajando en una rama de git y estaba listo para confirmar mis cambios, así que hice una confirmación con un mensaje de confirmación útil. Luego, distraídamente, hice cambios menores en el código que no vale la pena mantener. Ahora quiero cambiar ramas, pero git me da,

error: tiene cambios locales en "X"; No puede cambiar de rama.

¿Puedo cambiar de sucursal sin comprometerme? Si es así, ¿cómo puedo configurar esto? Si no, ¿cómo salgo de este problema? Quiero ignorar los cambios menores sin comprometerme y solo cambiar las ramas.


1
¿Creo que esto solo sucede cuando los cambios se organizan para confirmar pero no para confirmar? git checkout funciona bien para cambiar ramas si aún no ha organizado los archivos con git add o similar.
Jeremy Wall

1
Hola Jeremy, ¿qué quieres decir con 'puesta en escena'? Forzar al usuario a confirmar el archivo antes de las ramas de cambios no parece un gran flujo de trabajo. Por ejemplo, si estoy en el repositorio principal y quiero comprobar rápidamente algo en una rama. Tengo que confirmar el código al maestro primero, ¡incluso si el código está medio escrito! ¿Estás diciendo que, de hecho, debería ser posible pagar una sucursal en esta situación?
Daniel Farrell

@boyfarrell Puede usar 'Git stash' para guardar temporalmente los cambios sin comprometerse.
Howiecamp


1
cuando cambia a una rama sin confirmar los cambios en la rama anterior, git intenta fusionar los cambios en los archivos de la nueva rama. Si la fusión se realiza sin ningún conflicto, las ramas de intercambio serán exitosas y podrá ver los cambios en la nueva rama. Pero si ocurre un conflicto, obtendrá error: You have local changes to '<filename>'; cannot switch branches.y la rama no cambiará. puede hacerlo git checkout -m <branch-name>para fusionar conflictos y pagar a la sucursal y resolver conflictos usted mismo, o git checkout -f <branch-name>ignorar los cambios.
samad montazeri

Respuestas:


400

Necesita un estado limpio para cambiar las ramas. El pago de la sucursal solo se permitirá si no afecta a los 'archivos sucios' (como comenta Charles Bailey en los comentarios).

De lo contrario, deberías:

  • esconder su cambio actual o
  • reset --hard HEAD (si no le importa perder esos cambios menores) o
  • checkout -f (Al cambiar de rama, proceda incluso si el índice o el árbol de trabajo difieren de HEAD. Esto se usa para descartar cambios locales).

O, más recientemente:

Continúe incluso si el índice o el árbol de trabajo difieren de HEAD.
Tanto el índice como el árbol de trabajo se restauran para que coincidan con el objetivo de conmutación.

Esto difiere de git switch -m <branch-name>, lo que desencadena una fusión de tres vías entre la rama actual, el contenido de su árbol de trabajo y la nueva rama está hecha: de esa manera no perderá su trabajo en progreso.


34
"Se necesita un estado limpio para cambiar las ramas". solo es cierto si el cambio de rama afecta a los 'archivos sucios'.
CB Bailey

10
Para el método de almacenamiento, escribí "git stash save", "git checkout otherbranch", y finalmente "git stash pop".
Venkat D.

1
Actualmente no veo este mensaje de error, y los cambios que hice en una rama se muestran en la otra cuando hago "git status". ha cambiado algo?
Senthil A Kumar

2
Gracias. la salida -f fue lo que necesitaba. hice git reset --hard git clean -f git checkout mybranch -f
nologo

1
Aquí está la gran cosa que Git se equivocó totalmente al violar la definición básica de una rama. A diferencia de git branch, significa dos espacios de trabajo totalmente diferentes bifurcados de un repositorio.
nehem

125

Si desea descartar los cambios,

git checkout -- <file>
git checkout branch

Si quieres conservar los cambios,

git stash save
git checkout branch
git stash pop

10
De hecho, lo que Romerun dice (para completar): git stash save(cuando está en la rama de trabajo Y) entonces git checkout branchXhaga algo, git add/commit -metc. git checkout branchYy git stash poprecuperar el alijo
Highmastdon

2
Tal vez sea así. Sin embargo, tengo una situación en la que quiero hacer lo que dice la respuesta, si lo entiendo bien: esconder los cambios, cambiar de Y a X, luego hacer cambios y confirmarlos en X.
Ben Klein

1
Tenga en cuenta que git stash saveahora está en desuso a favor degit stash push
Argento

Este alias simplifica el caso de mantener cambios al cambiar ramas.
Tom Hale

62

bueno, debería ser

git stash save
git checkout branch
// do something
git checkout oldbranch
git stash pop

55
Sí, el alijo es global, no específico de la rama, si guardo pop después de cambiar de rama obtendré el mismo alijo que en la (s) otra (s) rama (s)
Aditya Mittal

66
Cabe señalar git stashtome por defectogit stash save
Charlie-Greenman

Gracias, es muy útil para mí
Govind Kumar


16

Tenga en cuenta que si ha fusionado sucursales remotas o tiene compromisos locales y desea volver al HEAD remoto, debe hacer lo siguiente:

git reset --hard origin/HEAD

HEAD solo solo se referirá al commit / merge local: varias veces he olvidado que al reiniciar y terminar con "su repositorio es X commits ahead .." cuando tenía la intención total de bombardear TODOS los cambios / commits y volver a la rama remota .


9

Si ha realizado cambios en los archivos que Git también necesita cambiar al cambiar de sucursal, no se lo permitirá. Para descartar cambios de trabajo, use:

git reset --hard HEAD

Luego, podrás cambiar de rama.


9

Ninguna de estas respuestas me ayudó porque todavía tenía archivos sin seguimiento incluso después de reiniciar y guardar. Tenía que hacer:

git reset --hard HEAD
git clean -d -f

4

cambiando a una nueva sucursal perdiendo cambios:

git checkout -b YOUR_NEW_BRANCH_NAME --force

cambio a una rama existente perdiendo cambios:

git checkout YOUR_BRANCH --force

4

Respuesta fácil:

es forzar el pago de una sucursal

git checkout -f <branch_name>

Forzar la verificación de una rama le dice a git que elimine todos los cambios que ha realizado en la rama actual y desproteja la deseada.

o en caso de que estés revisando un commit

git checkout -f <commit-hash>


"Pensé que podía cambiar las ramas sin comprometerme. Si es así, ¿cómo puedo configurar esto? Si no, ¿cómo salgo de este problema?"

La respuesta a eso es No , esa es literalmente la filosofía de Git: hacer un seguimiento de todos los cambios, y que cada nodo (es decir, commit) debe estar actualizado con los últimos cambios que haya realizado, a menos que haya hizo un nuevo compromiso, por supuesto.


¿Decidiste mantener los cambios?

Luego guárdelos usando

git stash

y luego para mostrar sus cambios en la rama deseada, use

git stash apply

que aplicará los cambios pero también los mantendrá en la cola oculta. Si no desea mantenerlos en la pila de alijo, entonces revíselos usando

git stash pop

Eso es el equivalente de applyy luegodrop


2

Cierre la terminal, elimine la carpeta donde está su proyecto, luego clone nuevamente su proyecto y listo.


2
¡git no está diseñado para empujarlo a eliminar el proyecto y clonar nuevamente! si quieres obtener la última versión desde el origen, ¡simplemente reset --hard!
Ahmed Nour Jamal El-Din

2

Si desea mantener los cambios y cambiar la rama en un comando de línea única

git stash && git checkout <branch_name> && git stash pop

1

Mover cambios no confirmados a una nueva sucursal

Creé un .gitconfigalias para esto:

[alias]
spcosp = !"git stash push && git checkout \"$@\" && git stash pop --index #"

Para cambiar a new-branch-name, use:

git spcosp new-branch-name

Y cualquier archivo no comprometido y cambios de índice se mantendrán.


1

git checkout -f your_branch_name

git checkout -f your_branch_name

Si tiene problemas para revertir los cambios:

git checkout .

si desea eliminar directorios y archivos sin seguimiento:

git clean -fd

0

Para cambiar a otra rama sin confirmar los cambios cuando git stash no funciona. Puede usar el siguiente comando:

git checkout -f nombre-sucursal

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.