¿Cómo puedo volver a mostrar mis archivos después de realizar una confirmación local?

268

He ejecutado el siguiente comando

git add <foo.java>
git commit -m "add the foo.java file"

¿Cómo puedo eliminar mi confirmación local ahora y quitar el escenario de foo.java?

Si escribo git reset --hard, descubrí que revierte mi modificado foo.javaal original.

Kit Ho
fuente

Respuestas:

452

git reset --soft HEAD~1Debes hacer lo que quieras. Después de esto, tendrá los primeros cambios en el índice (visibles con git diff --cached), y sus cambios más nuevos no se realizarán por etapas. git statusentonces se verá así:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.java
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.java
#

Luego puede hacer git add foo.javay confirmar ambos cambios a la vez.

Antti
fuente
Edité la respuesta: "Los cambios que se deben confirmar" tienen los primeros cambios, y "los cambios que no se realizan para confirmar" tienen los segundos cambios.
Antti
44
Lo que se describe en esta respuesta es en realidad lo que git commit --amendhace; pero con un flujo de trabajo mucho más complicado. Esto no responde a la pregunta que OP hizo, a pesar de dar una buena dirección ( git reset).
7heo.tk
2
Tuve que reemplazar el '^' con un '~' para que funcione, por lo que parece:git reset --soft HEAD~
Shahar
3
hacer git reset --Soft HEAD ~ 1 luego git reset HEAD
Joko Wandiro
respuesta perfecta a lo que quiero!
DeepInJava
78

Utilizar:

git reset HEAD^

Eso hace un restablecimiento "mixto" de forma predeterminada, que hará lo que solicitó; pon foo.java en unstaged, eliminando el commit más reciente.

Ryan Stewart
fuente
2
¿Te importaría explicarme qué es el reinicio "mixto", el reinicio "suave" y el reinicio "duro"?
Kit Ho
1
@Kit Ho - git reset manual tiene excelentes descripciones de estos.
manojlds
44
@Kit, @manojlds: también lo hace stackoverflow.com/questions/2530060/… (enchufe descarado)
Cascabel
55
Esa es en realidad la única respuesta correcta . Las otras dos respuestas en escena los archivos de nuevo después de hacer un commit.
7heo.tk
git reset --softno funcionó, pero lo git reset HEAD^hizo
palabras
43

Para mí, lo siguiente es la forma más legible (por lo tanto, preferible) de hacerlo:

git reset HEAD~1

En lugar de 1, podría haber cualquier cantidad de confirmaciones que desee eliminar.

Andrey Deineko
fuente
39

git reset --softes solo para eso: es como git reset --hard, pero no toca los archivos.

wRAR
fuente
44
¡Esa fue la explicación más fácil de entender que he escuchado hasta ahora (en solo 11 palabras)! ¡Gracias!
phreakhead
3
Esa respuesta es incorrecta. git reset"es como git reset --hardpero no toca los archivos". No git reset --soft. git reset --softorganizará los cambios, por lo que no tendrá que agregarlos a la puesta en escena en caso de que quiera cometerlos, pero tendrá que git resethacerlos (sí, una segunda vez y sin el --soft) en caso de que no lo haga. Entonces esa respuesta es corta, pero incorrecta.
7heo.tk
12

Para desestadificar todos los archivos en su última confirmación:

git reset HEAD~

Lavika
fuente
8

"Restablecer" es la forma de deshacer los cambios localmente. Cuando se compromete, primero selecciona los cambios para incluir con " git add ", eso se llama "puesta en escena". Y una vez que los cambios están organizados, entonces los " comprometes ".

Para retroceder ya sea desde la puesta en escena o la confirmación, "restablece" el HEAD. En una rama, HEAD es una variable git que apunta a la confirmación más reciente. Entonces, si ha organizado pero no se ha comprometido, " git reset HEAD ". Eso respalda al HEAD actual al quitar los cambios del escenario. Es la abreviatura de " git reset - HEAD mezclado ~ 0 ".

Si ya se ha comprometido, entonces HEAD ya ha avanzado, por lo que debe realizar una copia de seguridad de la confirmación anterior. Aquí " restablece HEAD ~ 1 " o " restablece HEAD ^ 1 " o " restablece HEAD ~ " o " restablece HEAD ^ " - todas las referencias HEAD menos una.

¿Cuál es el mejor símbolo, ~ o ^? Piense en ~ tilde como una secuencia única : cuando cada confirmación tiene un solo elemento primario y es solo una serie de cambios en secuencia, entonces puede hacer una copia de seguridad de la secuencia utilizando la tilde, como HEAD ~ 1, HEAD ~ 2, HEAD ~ 3, para padres, abuelos, bisabuelos, etc. (técnicamente es encontrar el primer padre en generaciones anteriores).

Cuando hay una fusión, los commits tienen más de un padre. Ahí es cuando entra en juego el ^ caret: puedes recordarlo porque muestra las ramas que se unen. Usando el símbolo de intercalación, HEAD ^ 1 sería el primer padre y HEAD ^ 2 sería el segundo padre de un solo padre, por ejemplo, madre y padre.

Entonces, si solo retrocede un salto en una confirmación de un solo padre, entonces HEAD ~ y HEAD ^ son equivalentes: puede usar cualquiera de los dos.

Además, el restablecimiento puede ser --soft , --mixed o --hard . Un reinicio por software simplemente retrocede la confirmación: restablece el HEAD, pero no extrae los archivos de la confirmación anterior, por lo que se conservan todos los cambios en el directorio de trabajo. Y - el reinicio suave ni siquiera borra el escenario (también conocido como el índice ), por lo que todos los archivos que se organizaron aún estarán en el escenario.

Un restablecimiento mixto (el valor predeterminado) tampoco comprueba los archivos de la confirmación anterior, por lo que se conservan todos los cambios, pero se borra la etapa. Es por eso que un simple " git reset HEAD " despejará del escenario.

Un restablecimiento completo restablece el HEAD y borra la etapa, pero también extrae todos los archivos de la confirmación anterior y sobrescribe cualquier cambio.

Si ha enviado el commit a un repositorio remoto, el reinicio no funciona tan bien. Puede restablecer localmente, pero cuando intente presionar hacia el control remoto, git verá que su HEAD local está detrás del HEAD en la rama remota y se negará a presionar. Es posible que pueda forzar el empuje, pero a git realmente no le gusta hacerlo.

Alternativamente, puede esconder sus cambios si desea conservarlos, verifique la confirmación anterior, retire los cambios, organícelos, cree una nueva confirmación y luego presione eso.

HieroB
fuente
+1 para la explicación detallada de la operación. OMI, esta debería ser la respuesta aceptada!
ISAE
2

Digamos que quieres eliminar los cambios de los cambios hasta n commits,

Donde commit hashes son los siguientes:

  • h1
  • h2 ...
  • hn
  • hn + 1

Luego ejecute el siguiente comando:
git reset hn

Ahora la CABEZA estará en hn + 1. Los cambios de h1 a hn no se realizarán.

Vasantha Ganesh K
fuente