Git empuja a la rama incorrecta

99

Trabajando con git, después de algunos 'commit' y un par de 'push', ¡me di cuenta de que estoy usando la rama incorrecta!

Ahora tengo que eliminar de alguna manera mis cambios en wrong_branch y confirmar e impulsar los cambios en right_branch

¿Cuál es la mejor (y sencilla) forma de hacerlo?

gracias

Alessandro De Simone
fuente
Buena pregunta @tokland: el 99% de los desarrolladores de ruby ​​usan git, y el proyecto en el que estoy trabajando está en RoR ... pero sé que esto no podría ser una buena motivación
Alessandro De Simone
3
Desde mi punto de vista, esto no es un duplicado de lo que comentó halfdan, ya que también se trata de mover las confirmaciones a otra rama, no solo eliminarlas.
olenz

Respuestas:

142

cambie a esa rama, verifique git logy git revertesas confirmaciones individualmente. Una vez que haya hecho eso, vuelva a la rama deseada y allí podrá usar git cherry-pickpara elegir confirmaciones específicas de las referencias de git y fusionarlas en la rama derecha.

git checkout wrong_branch
git revert commitsha1
git revert commitsha2
git checkout right_branch
git cherry-pick commitsha1
git cherry-pick commitsha2

Si las confirmaciones están agrupadas y no hay confirmaciones presionadas después de las confirmaciones sucias, incluso puede usar git resetpara llevar esa rama incorrecta a un estado justo antes de sus confirmaciones y luego seguir eso nuevamente git cherry-pickpara obtener sus confirmaciones en la rama correcta.

git checkout wrong_branch
git reset commitsha3 #commit just before commitsha2
git checkout right_branch
git cherry-pick commitsha1
git cherry-pick commitsha2
Dhruva Sagar
fuente
Revert + cherry-pick parece mucho más simple que otros métodos posibles que implican restablecer la cabeza y / o rebasar.
ChrisV
2
Para git cherry-pick, puede poner varios shas en una sola línea, es decir git cherry-pick commitsha1 commitsha2.
ThomasW
¡Salvador de la vida! Y no complicado. ¡Gracias!
Craig Silver
¿Qué sucede cuando desea fusionar wrong_branch (por ejemplo, desarrollar) en right_branch (por ejemplo, función / X), luego obtiene las reversiones deshaciendo los cambios que seleccionó?
timB33
revertes mucho más limpio y menos dramático que a resetmenos que realmente desee eliminar algo sensible (¿credenciales?)
Qumber hace
3

La forma más sencilla es utilizar git rebase. Suponga que tiene esa configuración:

A -- B -- C -- C1 -- C2 # right branch
          \
           \-- D -- C3 -- C4 # wrong branch

Quiere mover el cambio C3, C4 a la rama derecha.

git checkout -b new_wrong_branch D
git checkout wrong_branch
git rebase D --onto right_branch
git checkout right_branch
git merge right_branch wrong_branch
git branch -d wrong_branch
git branch rename new_wrong_branch wrong_branch

Ahora el escenario es

A -- B -- C -- C1 -- C2 -- C3 -- C4 # right_branch
          \
           \ -- D # wrong_branch

Entonces tienes que impulsar tus resultados con fuerza (SI nadie se ha sincronizado con tu repositorio remoto todavía):

git push -f remote:right_branch
Olivier Verdier
fuente
No probé esta solución, ya estaba trabajando en la primera respuesta (y funcionó). No he pensado en rebase, parece una buena alternativa, gracias
Alessandro De Simone
1
En lugar de git push -f, mejor uso git push --force-with-lease. Al menos, asegura que la referencia remota se actualizará solo si nadie presionó otras confirmaciones sobre sus confirmaciones.
Pierre-Olivier Vares
2

Un pequeño atajo que se agrega a la respuesta de Dhruva.

git checkout wrong_branch
git revert commitsha1

git checkout right_branch
git push right_branch

git checkout wrong_branch
git reset commitsha2 #commit just before commitsha1
git push wrong_branch -f
tarikakyol
fuente