En un repositorio local, acabo de ejecutar git cherry-pick SHAsin ningún conflicto o problema. Entonces me di cuenta de que no quería hacer lo que acababa de hacer. No lo he empujado a ninguna parte.
¿Cómo puedo quitar solo esta selección de cereza?
Me gustaría saber si hay una forma de hacer esto:
- cuando tengo otros cambios locales
- cuando no tengo otros cambios locales
Preferiblemente con un comando para ambos casos si es posible.

Para deshacer su última confirmación, simplemente haga
git reset --hard HEAD~.Editar : esta respuesta se aplicó a una versión anterior de la pregunta que no mencionaba la preservación de los cambios locales; la respuesta aceptada de Tim es de hecho la correcta. Gracias a qwertzguy por el aviso.
fuente
HEAD) es más robusto: considere el desafortunado caso dondeheadestá el nombre de una referencia existente.Si es posible, evite los reinicios bruscos. Los reinicios duros son una de las pocas operaciones destructivas en git. Afortunadamente, puedes deshacer una selección sin reiniciar y evitar cualquier cosa destructiva.
Tenga en cuenta el hash de la selección que desea deshacer, digamos que lo es
${bad_cherrypick}. Hacer ungit revert ${bad_cherrypick}. Ahora el contenido de su árbol de trabajo es como estaba antes de su mala elección.Repita su
git cherry-pick ${wanted_commit}, y cuando esté satisfecho con la nueva selección de cereza, haga ungit rebase -i ${bad_cherrypick}~1. Durante el rebase, elimine ambos${bad_cherrypick}y su correspondiente reversión.La rama en la que está trabajando solo tendrá la mejor selección. ¡No se necesitan reinicios!
fuente
git reflogpuede venir a tu rescate.Escríbalo en su consola y obtendrá una lista de su historial de git junto con SHA-1 que los representa.
Simplemente revise cualquier SHA-1 al que desee volver
Antes de responder, agreguemos algunos antecedentes, explicando qué es esto
HEAD.First of all what is HEAD?HEADes simplemente una referencia a la confirmación actual (más reciente) en la rama actual.Solo puede haber uno
HEADen un momento dado. (excluyendogit worktree)El contenido de
HEADse almacena adentro.git/HEADy contiene los 40 bytes SHA-1 de la confirmación actual.detached HEADSi no está en la última confirmación, lo que significa que
HEADapunta a una confirmación anterior en el historial, se llamadetached HEAD.En la línea de comando, se verá así: SHA-1 en lugar del nombre de la rama, ya
HEADque no apunta a la punta de la rama actualAlgunas opciones sobre cómo recuperarse de un HEAD desprendido:
git checkoutEsto comprobará una nueva rama que apunta a la confirmación deseada.
Este comando se ejecutará en una confirmación determinada.
En este punto, puede crear una rama y comenzar a trabajar a partir de este punto.
git reflogSiempre puedes usar el
reflogtambién.git reflogmostrará cualquier cambio que haya actualizadoHEADy comprobar la entrada de reflog deseada volverá a establecerHEADesta confirmación.Cada vez que se modifica HEAD habrá una nueva entrada en el
reflogEsto te llevará de regreso a tu compromiso deseado
git reset --hard <commit_id>"Mueve" tu HEAD de nuevo a la confirmación deseada.
también puedes usar el
git rebase --no-autostash.git revert <sha-1>"Deshacer" el compromiso dado o el rango de compromiso.
El comando de reinicio "deshará" cualquier cambio realizado en la confirmación dada.
Se confirmará una nueva confirmación con el parche para deshacer, mientras que la confirmación original también permanecerá en el historial.
Este esquema ilustra qué comando hace qué.
Como puede ver,
reset && checkoutmodifique elHEAD.fuente
git reset --hardEnfrentado con este mismo problema, descubrí que si se ha comprometido y / o empujado al control remoto desde su selección de cereza exitosa, y desea eliminarlo, puede encontrar el SHA de la selección de cereza ejecutando:
git log --graph --decorate --onelineLuego, (después de usar
:wqpara salir del registro) puede eliminar la selección de cereza usandogit rebase -p --onto YOUR_SHA_HERE^ YOUR_SHA_HEREdonde
YOUR_SHA_HEREes igual al SHA de 40 o 7 caracteres abreviado de la confirmación seleccionada con precisión.Al principio, no podrá impulsar sus cambios porque su repositorio remoto y su repositorio local tendrán diferentes historiales de confirmación. Puede forzar a sus confirmaciones locales a reemplazar lo que está en su control remoto usando
git push --force origin YOUR_REPO_NAME(Adapté esta solución de Seth Robertson : consulte "Eliminación de una confirmación completa").
fuente
Un comando y no usa el
git resetcomando destructivo :GIT_SEQUENCE_EDITOR="sed -i 's/pick/d/'" git rebase -i HEAD~ --autostashSimplemente elimina la confirmación, lo que lo vuelve a colocar exactamente en el estado anterior a la selección, incluso si tenía cambios locales.
fuente
git reset HEAD^hacegit resetdeshace la acción de confirmación sin eliminar ninguno de los cambios. Te recomiendo leer git-scm.com/docs/git-reset . La pregunta de OP es deshacer una selección selectiva. Pruebe ambos comandos, el mío lo pondrá de nuevo en el estado exacto en el que estaba antes de la selección.git resetarruinará su árbol de trabajo cuando deje los cambios seleccionados y se volverán indistinguibles de sus cambios locales preexistentes.reset --hard. No deja cambiosgit reset --hardes un comando destructivo que también eliminará los cambios locales no relacionados y lo hará de una manera irrecuperable. Entonces eso no es lo que pidió el OP.sedestá haciendo ese comando, en qué se diferencia de hacerlo manualmente y qué--autostashhace.