¿Cómo puedes deshacer el último git add?

193

¿Es posible destrabar el último cambio organizado (no comprometido) en git ? Supongamos que hay muchos archivos en la rama actual, algunos organizados, otros no. En algún momento, un programador tonto ejecutó accidentalmente:

git add -- .

...en vez de:

git checkout -- .

¿Puede este programador ahora mostrar sus últimos cambios con algún comando mágico de git ? ¿O debería haberse comprometido antes de experimentar en primer lugar?

Septagrama
fuente
Je Sin embargo, obtuvimos una útil pregunta y respuesta.
steveha
2
posible duplicado de Deshacer 'git add' antes de confirmar
Jim Fell
Creo que no es el duplicado. OP en la otra pregunta es pedir una forma de deshacer esto o eliminar estos archivos del commit. Quiero (ed) con precisión y solo deshacer los cambios que se agregaron con el último git addcomando, especialmente para los archivos que ya tenían cambios organizados, y que tenían algunos cambios que debían deshacerse, no organizarse. Sin embargo, no puedo decir que la otra pregunta no esté relacionada.
Septagram
1
Quizás debería haber estado / comprometido / comprometido antes de experimentar en primer lugar.
android.weasel
@ android.weasel sí, eso fue hace muchos años ...
Septagram

Respuestas:

299

Puedes usar git reset. Esto 'desestabilizará' todos los archivos que haya agregado después de su última confirmación.

Si solo quiere quitar el escenario de algunos archivos, úselos git reset -- <file 1> <file 2> <file n>.

También es posible eliminar algunos de los cambios en los archivos mediante el uso git reset -p.

thameera
fuente
3
Qué triste. Supongo que hay algo mal en mis prácticas de compromiso después de todo. Aceptando esta respuesta, porque mencionaste el -pinterruptor. ¡Gracias! :)
Septagram
Genera (para mí) el error: fatal: no se pudo resolver 'HEAD' como una referencia válida. Todavía no he comprometido nada (nuevo repositorio), solo he hecho git add. y lo lamenté. No quiero restablecer todo el complemento, solo un directorio. git reset - dir /*.* genera el error anterior.
Francis Davey el
... Ah, ya veo lo que me está pasando. Todavía no tenía nada que señalar HEAD, por lo que git reset falló (porque funciona en HEAD).
Francis Davey
42

No puede deshacer el último git add, pero puede deshacer todos los correos addelectrónicos desde la última confirmación. git resetsin un argumento de confirmación restablece el índice (cambios por etapas sin etapas):

git reset
knittl
fuente
2
"No puedes deshacer el último git add": Wow, esto es sorprendente y potencialmente doloroso. ¿Hay una fuente definitiva para esto? Además, ¿hay alguna buena razón para que sea así? ¡Gracias!
Andrew Moylan
@ AndrewMoylan: bueno, no hay una forma automática de hacerlo. Siempre puedes resetusar un solo archivo o usarlo reset -ppara quitar el escenario de un trozo específico.
knittl
15

Entonces la verdadera respuesta a

¿Puede este programador ahora mostrar sus últimos cambios con algún comando mágico de git?

es en realidad: No, no puedes quitar el escenario solo el último git add.

Eso es si interpretamos la pregunta como en la siguiente situación:

Archivo inicial:

void foo() {

}

main() {
    foo();
}

Primer cambio seguido de git add:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

Segundo cambio seguido de git add:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

En este caso, git reset -pno ayudará, ya que su granularidad más pequeña son las líneas. gitno sabe eso sobre el estado intermedio de:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

nunca más.

stanm
fuente
Me entusiasmó porque, como nuevo usuario de git, esa es una distinción realmente importante que resalta lo que mis amigos describen como "tener una buena higiene en el registro" ... mi experiencia personal: se describió como "compartir el automóvil" (¡malo!).
benc
3

En la fecha, git pregunta:

  1. use "git rm --cached <file>..." to unstagesi los archivos no estaban en el repositorio. Desestabiliza los archivos manteniéndolos allí.
  2. use "git reset HEAD <file>..." to unstagesi los archivos estaban en el repositorio y los agrega como modificados. Mantiene los archivos como están y los desestabiliza.

Que yo sepa, no puede deshacer el, git add --pero puede eliminar una lista de archivos como se mencionó anteriormente.

theGiallo
fuente
2
  • Elimine el archivo del índice, pero manténgalo versionado y deje cambios sin confirmar en la copia de trabajo:

    git reset head <file>
    
  • Restablezca el archivo al último estado desde HEAD, deshaciendo los cambios y eliminándolos del índice:

    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>

    Esto es necesario ya git reset --hard HEADque no funcionará con archivos individuales.

  • Eliminar <file>del índice y el control de versiones, manteniendo el archivo sin versión con cambios en la copia de trabajo:

    git rm --cached <file>
    
  • Eliminar <file>de la copia de trabajo y el control de versiones por completo:

    git rm <file>
    
Faisal
fuente
2

Si desea eliminar todos los archivos agregados de git para commit

git reset

Si desea eliminar un archivo individual

git rm <file>
BSB
fuente
1

Puedes usar

git reset

para deshacer los archivos locales recientemente agregados

 git reset file_name

para deshacer los cambios para un archivo específico

ireshika piyumalie
fuente
0

Dependiendo del tamaño y la escala de la dificultad, puede crear una rama temporal (temporal) y comprometer el trabajo actual allí.

Luego, cambie a su sucursal original, y seleccione los archivos apropiados del scratch commit.

Al menos tendría un registro permanente de los estados actuales y anteriores para trabajar (hasta que elimine esa rama temporal).

Philip Oakley
fuente