En un repositorio local, acabo de ejecutar git cherry-pick SHA
sin 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 dondehead
está 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 reflog
puede 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?
HEAD
es simplemente una referencia a la confirmación actual (más reciente) en la rama actual.Solo puede haber uno
HEAD
en un momento dado. (excluyendogit worktree
)El contenido de
HEAD
se almacena adentro.git/HEAD
y contiene los 40 bytes SHA-1 de la confirmación actual.detached HEAD
Si no está en la última confirmación, lo que significa que
HEAD
apunta 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
HEAD
que no apunta a la punta de la rama actualAlgunas opciones sobre cómo recuperarse de un HEAD desprendido:
git checkout
Esto 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 reflog
Siempre puedes usar el
reflog
también.git reflog
mostrará cualquier cambio que haya actualizadoHEAD
y comprobar la entrada de reflog deseada volverá a establecerHEAD
esta confirmación.Cada vez que se modifica HEAD habrá una nueva entrada en el
reflog
Esto 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 && checkout
modifique elHEAD
.fuente
git reset --hard
Enfrentado 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 --oneline
Luego, (después de usar
:wq
para salir del registro) puede eliminar la selección de cereza usandogit rebase -p --onto YOUR_SHA_HERE^ YOUR_SHA_HERE
donde
YOUR_SHA_HERE
es 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 reset
comando destructivo :GIT_SEQUENCE_EDITOR="sed -i 's/pick/d/'" git rebase -i HEAD~ --autostash
Simplemente 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 reset
deshace 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 reset
arruinará 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 --hard
es 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.sed
está haciendo ese comando, en qué se diferencia de hacerlo manualmente y qué--autostash
hace.