Pregunta ¿Puedo eliminar un commit de git pero mantener los cambios?


En una de mis ramas de desarrollo, realicé algunos cambios en mi base de código. Antes de poder completar las funciones en las que estaba trabajando, tuve que cambiar mi rama actual a principal para probar algunas características. Pero el simple hecho de usar un "maestro de git checkout" conservó los cambios que también realicé en mi rama de desarrollo, rompiendo parte de la funcionalidad en el maestro. Entonces, lo que hice fue comprometer los cambios en mi rama de desarrollo con un mensaje de confirmación "commit temporal" y luego checkout master para la demostración.

Ahora que terminé la demostración y volví a trabajar en mi rama de desarrollo, me gustaría eliminar la "confirmación temporal" que hice mientras aún conservaba los cambios que hice. ¿Es eso posible?


516
2018-04-02 18:56


origen


Respuestas:


Es tan simple como esto:

git reset HEAD^

git reset sin un --hard o --soft mueve tu HEAD para apuntar a la confirmación especificada, sin cambiar ningún archivo. HEAD^ se refiere a la (primera) confirmación principal de su confirmación actual, que en su caso es la confirmación antes de la temporal.

Tenga en cuenta que otra opción es continuar de forma normal y, en su lugar, ejecutar en el siguiente punto de confirmación:

git commit --amend [-m … etc]

que en cambio editar la confirmación más reciente, que tiene el mismo efecto que el anterior.

Tenga en cuenta que esto (al igual que con casi todas las respuestas de git) puede causar problemas si ya ha empujado el compromiso incorrecto a un lugar donde alguien más lo haya extraído. Intenta evitar eso


856
2018-04-02 18:58



Hay dos formas de manejar esto. Lo que es más fácil depende de tu situación

Reiniciar

Si la confirmación de la que desea deshacerse fue la última confirmación y no ha realizado ningún trabajo adicional, simplemente puede usar git-reset

git reset HEAD^

Toma su rama de nuevo a la confirmación justo antes de su CABEZA actual. Sin embargo, en realidad no cambia los archivos en su árbol de trabajo. Como resultado, los cambios que se encontraban en esa confirmación aparecen como modificados, es como un comando 'no comprometido'. De hecho, tengo un alias para hacer exactamente eso.

git config --global alias.uncommit 'reset HEAD^'

Entonces puedes simplemente usar git uncommit en el futuro para respaldar un commit.

Aplastamiento

Reducir un compromiso significa combinar dos o más commits en uno. Lo hago con bastante frecuencia. En su caso, tiene la función de medio hecho, y luego la finalizará y volverá a comprometerse con el mensaje de compromiso correcto y permanente.

git rebase -i <ref>

Digo arriba porque quiero dejar en claro que esto podría ser cualquier cantidad de confirmaciones. correr git log y encuentre la confirmación de la que desea deshacerse, copie su SHA1 y úselo en lugar de <ref>. Git lo llevará al modo rebase interactivo. Mostrará todas las confirmaciones entre su estado actual y lo que ponga en lugar de <ref>. Así que si <ref> es 10 commits ago, le mostrará los 10 commits.

Delante de cada compromiso, tendrá la palabra pick. Encuentre el compromiso del que desea deshacerse y cámbielo de pick a fixup o squash. Utilizando fixup simplemente descarta el mensaje de confirmación y fusiona los cambios en su predecesor inmediato en la lista. los squash La palabra clave hace lo mismo, pero le permite editar el mensaje de confirmación de la nueva confirmación combinada.

Tenga en cuenta que las confirmaciones se volverán a comprometer en el orden en que aparecen en la lista cuando salga del editor. Por lo tanto, si realizó una confirmación temporal, luego realizó otro trabajo en la misma rama y completó la función en una confirmación posterior, el uso de rebase le permitirá volver a ordenar las confirmaciones y aplastarlas.

ADVERTENCIA:

Rebasing modifica el historial: NO haga esto con las confirmaciones que ya haya compartido con otros desarrolladores.

Stashing

En el futuro, para evitar este problema, considere usar git stash para almacenar temporalmente trabajo no confirmado.

git stash save 'some message'

Esto almacenará sus cambios actuales en un lado en su lista oculta. Arriba está la versión más explícita del comando stash, lo que permite un comentario para describir lo que escondes. También puedes simplemente correr git stash y nada más, pero no se almacenará ningún mensaje.

Puede navegar por su lista oculta con ...

git stash list

Esto le mostrará todos sus escondites, en qué ramas se realizaron, y el mensaje y al comienzo de cada línea, e identificador para ese alijo que se parece a esto stash@{#} donde # es su posición en la matriz de depósitos.

Para restaurar un alijo (que se puede hacer en cualquier rama, independientemente de dónde se creó originalmente el alijo) simplemente ejecuta ...

git stash apply stash@{#}

Nuevamente, no # es la posición en la matriz de depósitos. Si el alijo que desea restaurar está en el 0 posición, es decir, si fue el alijo más reciente. Entonces solo puedes ejecutar el comando sin especificar la posición de escondite, git asumirá que te refieres al último: git stash apply.

Entonces, por ejemplo, si me encuentro trabajando en la rama incorrecta, puedo ejecutar la siguiente secuencia de comandos.

git stash
git checkout <correct_branch>
git stash apply

En su caso, se movió un poco más por las ramas, pero la misma idea todavía se aplica.

Espero que esto ayude.


98
2018-04-03 03:55



Sí, puede eliminar su confirmación sin eliminar los cambios:     git reset @ ~


16
2017-08-23 18:44



Creo que estás buscando esto

git reset --soft HEAD ~ 1

te llevará a la confirmación anterior y mantendrás los cambios que hayas realizado.


13
2018-03-09 09:57



En mi caso, ya presioné al repositorio. ¡Ay!

Puede revertir una confirmación específica mientras mantiene los cambios en sus archivos locales haciendo:

git revert -n <sha>

De esta forma pude mantener los cambios que necesitaba y deshice una confirmación que ya había sido enviada.


4
2018-05-18 14:20



Usando git 2.9 (precisamente 2.9.2.windows.1) git reset HEAD^ pide más; no estoy seguro de qué entrada se espera aquí. Por favor, consulte la captura de pantalla a continuación

enter image description here

Encontrado otra solución git reset HEAD~#numberOfCommits con el cual podemos elegir seleccionar la cantidad de confirmaciones locales que desea restablecer manteniendo intactos sus cambios. Por lo tanto, tenemos la oportunidad de descartar todas las confirmaciones locales, así como la cantidad limitada de confirmaciones locales.

Consulte a continuación las capturas de pantalla que muestran git reset HEAD~1 en acción: enter image description here

enter image description here


3
2017-11-22 10:03



Una forma más de hacerlo.

Agregue commit en la parte superior de la confirmación temporal y luego haga lo siguiente:

git rebase -i

Para fusionar dos commits en uno (el comando abrirá un archivo de texto con instrucciones explícitas, edítelo).


2
2018-04-02 19:59