it-swarm-es.com

¿Cómo deshacer 'git add' antes de confirmar?

Por error, agregué archivos a git usando el comando:

git add myfile.txt

Todavía no he ejecutado git commit. ¿Hay una manera de deshacer esto, por lo que estos archivos no se incluirán en la confirmación?


Hay 48 respuestas hasta ahora (algunas eliminadas). Por favor, no agregue uno nuevo a menos que tenga alguna información nueva.

8101
paxos1977

Puede deshacer git add antes de confirmar con

git reset <file>

que lo eliminará del índice actual (la lista de "a punto de comprometerse") sin cambiar nada más.

Puedes usar

git reset

sin ningún nombre de archivo para eliminar todos los cambios debidos. Esto puede ser útil cuando hay demasiados archivos para ser listados uno por uno en un tiempo razonable.

En las versiones anteriores de Git, los comandos anteriores son equivalentes a git reset HEAD <file> y git reset HEAD respectivamente, y fallarán si HEAD no está definido (porque aún no ha realizado ningún confirmación en su repo) o ambiguo (porque creó una rama llamada HEAD, la cual Es una estupidez que no debes hacer). Sin embargo, esto se modificó en Git 1.8.2 , por lo tanto, en las versiones modernas de Git, puedes usar los comandos anteriores incluso antes de hacer tu primera confirmación:

"git reset" (sin opciones o parámetros) se utiliza para errores cuando no tiene ningún tipo de confirmación en su historial, pero ahora le da un índice vacío (para que coincida con la confirmación inexistente en la que ni siquiera está).

9181
genehack

Usted quiere:

git rm --cached <added_file_to_undo>

Razonamiento:

Cuando era nuevo en esto, primero intenté

git reset .

(para deshacer todo mi agregado inicial), solo para recibir este (no tan) útil mensaje:

fatal: Failed to resolve 'HEAD' as a valid ref.

Resulta que esto se debe a que HEAD ref (branch?) No existe hasta después de la primera confirmación. Es decir, se encontrará con el mismo problema de principiante que yo si su flujo de trabajo, como el mío, fuera algo como:

  1. cd a mi gran directorio de nuevos proyectos para probar Git, el nuevo hotness
  2. git init
  3. git add .
  4. git status

    ... un montón de rollos de basura por ...

    => Maldita sea, no quería añadir todo eso.

  5. google "undo git add"

    => encontrar Desbordamiento de pila - yay

  6. git reset .

    => fatal: no se pudo resolver 'HEAD' como una referencia válida.

Resulta además que hay un error registrado en contra de la inutilidad de esto en la lista de correo.

Y que la solución correcta estaba allí mismo en la salida de estado de Git (que, sí, pasé por alto como 'basura')

...
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
...

Y, de hecho, la solución es utilizar git rm --cached FILE.

Tenga en cuenta las advertencias en otros lugares aquí: git rm elimina su copia de trabajo local del archivo, pero no si usa --cached . Aquí está el resultado de git help rm:

--cached Use esta opción para separar y eliminar rutas solo del índice. Los archivos del árbol de trabajo, ya sean modificados o no, se dejarán.

Procedo a usar

git rm --cached .

para eliminar todo y empezar de nuevo. Sin embargo, no funcionó, porque mientras add . es recursivo, resulta que rm necesita -r para recursionar. Suspiro.

git rm -r --cached .

Bien, ahora estoy de vuelta a donde empecé. La próxima vez voy a usar -n para hacer un recorrido en seco y ver qué se agregará:

git add -n .

Guardé todo en un lugar seguro antes de confiar en git help rm sobre el --cached que no destruye nada (y si lo escribo mal).

2047
Rhubarb

Si escribe:

git status

git le dirá lo que está en escena, etc., incluidas las instrucciones sobre cómo anular la etapa:

use "git reset HEAD <file>..." to unstage

Me parece que Git hace un buen trabajo al obligarme a hacer lo correcto en situaciones como esta.

Nota: las versiones recientes de git (1.8.4.x) han cambiado este mensaje:

(use "git rm --cached <file>..." to unstage)
507
Paul Beckingham

Para aclarar: git add mueve los cambios del directorio de trabajo actual al área de preparación (índice).

Este proceso se llama puesta en escena. Así que el comando más natural para etapa los cambios (archivos modificados) es el obvio:

git stage

git add es más fácil de escribir alias para git stage

Lástima que no haya comandos git unstage ni git unadd. El relevante es más difícil de adivinar o recordar, pero es bastante obvio:

git reset HEAD --

Podemos crear fácilmente un alias para esto:

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

Y finalmente, tenemos nuevos comandos:

git add file1
git stage file2
git unadd file2
git unstage file1

Personalmente uso alias aún más cortos:

git a #for staging
git u #for unstaging
238
takeshin

Además de la respuesta aceptada, si su archivo agregado por error fue enorme, probablemente notará que, incluso después de eliminarlo del índice con 'git reset', parece que todavía ocupa espacio en el directorio .git. Esto no es nada de qué preocuparse, el archivo todavía está en el repositorio, pero solo como un "objeto suelto", no se copiará a otros repositorios (a través de clonación, Push), y el espacio se recuperará eventualmente, aunque Tal vez no muy pronto. Si estás ansioso, puedes correr:

git gc --Prune=now

Actualizar (lo que sigue es mi intento de aclarar algunas confusiones que pueden surgir de las respuestas más votadas):

Entonces, ¿cuál es el real deshacer de git add?

git reset HEAD <file>?

o

git rm --cached <file>?

Estrictamente hablando, y si no me equivoco: ninguno .

git add no se puede deshacer - de forma segura, en general.

Recordemos primero lo que realmente hace git add <file>:

  1. Si <file> fue no rastreado previamente , git add lo agrega al caché , con su contenido actual.

  2. Si <file> fue ya fue rastreado , git add guarda el contenido actual (instantánea, versión) en el caché. En GIT, esta acción todavía se llama add , (no meramente update it), porque dos versiones diferentes (snapshots) de un archivo se consideran como dos elementos diferentes: por lo tanto, estamos agregando un nuevo elemento en la memoria caché, que finalmente se compromete más tarde.

A la luz de esto, la pregunta es ligeramente ambigua:

Añadí erróneamente archivos usando el comando ...

El escenario de OP parece ser el primero (archivo sin seguimiento), queremos que el "deshacer" elimine el archivo (no solo el contenido actual) de los elementos rastreados. Si este es el caso, entonces está bien ejecutar git rm --cached <file>.

Y también podríamos ejecutar git reset HEAD <file>. En general, esto es preferible porque funciona en ambos escenarios: también se deshace cuando agregamos erróneamente una versión de un elemento ya rastreado.

Pero hay dos advertencias.

Primero: hay (como se señala en la respuesta) solo un escenario en el que git reset HEAD no funciona, pero git rm --cached sí lo hace: un nuevo repositorio (sin confirmaciones). Pero, en realidad, este es un caso prácticamente irrelevante.

Segundo: tenga en cuenta que git reset HEAD no puede recuperar mágicamente el contenido del archivo previamente almacenado en caché, simplemente lo vuelve a sincronizar desde HEAD. Si nuestro git add mal guiado sobrescribió una versión anterior no comprometida, no podemos recuperarla. Es por eso que, estrictamente hablando, no podemos deshacer [*].

Ejemplo:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # first add  of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt   
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # oops we didn't mean this
$ git reset HEAD file.txt  # undo ?
$ git diff --cached file.txt  # no dif, of course. stage == HEAD
$ git diff file.txt   # we have lost irrevocably "version 2"
-version 1
+version 3

Por supuesto, esto no es muy importante si seguimos el flujo de trabajo perezoso habitual de hacer 'git add' solo para agregar archivos nuevos (caso 1), y actualizamos los nuevos contenidos a través del comando commit, git commit -a.


* (Edición: lo anterior es prácticamente correcto, pero aún puede haber algunas formas leves/complicadas para recuperar los cambios que se realizaron, pero no se confirmaron y se sobrescribieron, consulte los comentarios de Johannes Matokic y iolsmit)

161
leonbloy
git rm --cached . -r

"anulará" todo lo que ha agregado de su directorio actual de forma recursiva

91
braitsch

Correr

git gui

y elimine todos los archivos manualmente o seleccionándolos todos y haciendo clic en el botón unstage from commit .

85
Khaja Minhajuddin

Deshacer un archivo que ya se agregó es bastante fácil usando git , para restablecer myfile.txt que ya se agregó, use:

git reset HEAD myfile.txt

Explica:

Después de configurar los archivos no deseados, para deshacer, puede hacer git reset, Head es la cabecera de su archivo en local y el último parámetro es el nombre de su archivo.

Creo los pasos en la imagen a continuación con más detalles para usted, incluidos todos los pasos que pueden ocurrir en estos casos:

 git reset HEAD file

82
Alireza

Git tiene comandos para cada acción imaginable, pero necesita un amplio conocimiento para hacer las cosas bien y por eso es contraintuitivo en el mejor de los casos ...

Lo que hiciste antes:

  • Se modificó un archivo y se usó git add ., o git add <file>.

Lo que quieras:

  • Elimine el archivo del índice, pero manténgalo actualizado y deje con los cambios no confirmados en la copia de trabajo:

    git reset head <file>
    
  • Restablezca el archivo al último estado desde HEAD, deshaga los cambios y elimínelos del índice:

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

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

  • Elimine <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>
    
  • Elimine <file> de la copia de trabajo y las versiones completamente:

    git rm <file>
    
80
sjas

La pregunta no está planteada claramente. La razón es que git add tiene dos significados:

  1. agregando un nuevo archivo al área de preparación, luego deshaga con git rm --cached file.
  2. agregar un archivo modificado al área de preparación, luego deshacer con git reset HEAD file.

en caso de duda, usar

git reset HEAD file

Porque hace lo esperado en ambos casos.

Advertencia: si hace git rm --cached file en un archivo que fue modificado (un archivo que existía antes en el repositorio), ¡entonces el archivo se eliminará en git commit! Seguirá existiendo en su sistema de archivos, pero si alguien más extrae su confirmación, el archivo se eliminará de su árbol de trabajo.

git status le dirá si el archivo era un nuevo archivo o modificado:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   my_new_file.txt
    modified:   my_modified_file.txt
71
Michael_Scharf

Si está en su confirmación inicial y no puede usar git reset, simplemente declare "Git quiebra", elimine la carpeta .git y comience

61
Paul Betts

Según muchas de las otras respuestas, puede usar git reset

PERO:

Encontré esta pequeña publicación que en realidad agrega el comando Git (bueno, un alias) para git unadd: vea git unadd para más detalles o ...

Simplemente,

git config --global alias.unadd "reset HEAD"

Ahora usted puede

git unadd foo.txt bar.txt
55
electblake

git remove o git rm se pueden utilizar para esto, con el indicador --cached. Tratar:

git help rm
46
gnud

Utilice git add -i para eliminar los archivos recién agregados de su próxima confirmación. Ejemplo:

Agregando el archivo que no querías:

$ git add foo
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   foo
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]#

Entrando en el complemento interactivo para deshacer el agregado (los comandos que se escriben en git aquí son "r" (revertir), "1" (la primera entrada en la lista revertir muestra), 'regresar' para salir del modo revertir y "q" (dejar):

$ git add -i
           staged     unstaged path
  1:        +1/-0      nothing foo

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +1/-0      nothing [f]oo
Revert>> 1
           staged     unstaged path
* 1:        +1/-0      nothing [f]oo
Revert>> 
note: foo is untracked now.
reverted one path

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> q
Bye.
$

¡Eso es! Aquí está su prueba, que muestra que "foo" está de vuelta en la lista sin seguimiento:

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]
#       foo
nothing added to commit but untracked files present (use "git add" to track)
$
42
Alex North-Keys

Aquí hay una manera de evitar este problema desconcertante al iniciar un nuevo proyecto:

  • Crea el directorio principal para tu nuevo proyecto.
  • Ejecuta git init.
  • Ahora crea un archivo .gitignore (incluso si está vacío).
  • Confíe su archivo .gitignore.

Git hace que sea muy difícil hacer git reset si no tienes ningún commit. Si crea un pequeño compromiso inicial solo por tener uno, después de eso puede git add -A y git reset tantas veces como desee para que todo salga bien.

Otra ventaja de este método es que si tiene problemas de final de línea más tarde y necesita actualizar todos sus archivos, es fácil:

  • Echa un vistazo a ese compromiso inicial. Esto eliminará todos tus archivos.
  • Entonces revisa tu compromiso más reciente otra vez. Esto recuperará copias nuevas de sus archivos, usando su configuración de final de línea actual.
37
Ryan Lundy

Tal vez Git haya evolucionado desde que publicaste tu pregunta.

$> git --version
git version 1.6.2.1

Ahora, puedes probar:

git reset HEAD .

Esto debería ser lo que estás buscando.

33
Kokotte23

Tenga en cuenta que si no especifica una revisión, debe incluir un separador. Ejemplo desde mi consola:

git reset <path_to_file>
fatal: ambiguous argument '<path_to_file>': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

git reset -- <path_to_file>
Unstaged changes after reset:
M   <path_to_file>

(git version 1.7.5.4)

33
powlo

Para eliminar archivos nuevos del área de preparación (y solo en el caso de un archivo nuevo), como se sugirió anteriormente:

git rm --cached FILE

Utilice rm --cached solo para los nuevos archivos añadidos accidentalmente.

30
Ran

Para restablecer cada archivo en una carpeta particular (y sus subcarpetas), puede usar el siguiente comando:

git reset *
24
Zorayr

use el comando * para manejar múltiples archivos a la vez

git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*

etc

24
boulder_ruby

Simplemente escriba git reset, se revertirá y es como si nunca hubiera escrito git add . desde su última confirmación. Asegúrate de que has cometido antes.

22
Donovan

Supongamos que creo un nuevo archivo newFile.txt.

 enter image description here

Supongamos que agrego el archivo accidentalmente, git add newFile.txt

 enter image description here

Ahora quiero deshacer este complemento, antes de confirmar, git reset newFile.txt

 enter image description here

18
Vidura Mudalige

Para un archivo específico:

  • git reset my_file.txt
  • git checkout my_file.txt

Para todos los archivos agregados:

  • git reset.
  • pago de git.

Nota: checkout cambia el código en los archivos y pasa al último estado actualizado (confirmado). reiniciar no cambia los códigos; simplemente restablece el encabezado.

17
Hasib Kamal

Para deshacer git añadir uso

git reset filename

13
Anirudh Sood

Este comando deshará tus cambios:

git reset HEAD filename.txt

También puedes usar

git add -p 

para añadir partes de archivos.

13
wallerjake

Me sorprende que nadie mencione el modo interactivo:

git add -i

elija la opción 3 para anular la adición de archivos. En mi caso, a menudo quiero agregar más de un archivo, con el modo interactivo puedes usar números como este para agregar archivos. Esto tomará todos menos 4: 1,2,3,5

Para elegir una secuencia, simplemente escriba 1-5 para tomar todo del 1 al 5.

Git staging archivos

13
Jonathan

git add myfile.txt # esto agregará su archivo a la lista de confirmados

Muy opuesto a este comando es,

git reset HEAD myfile.txt  # this will undo it. 

así, estarás en estado anterior. especificado volverá a estar en la lista sin seguimiento (estado anterior).

se restablecerá su cabeza con ese archivo especificado. así que, si tu cabeza no lo tiene, significa que simplemente lo restablecerá

9
Silent Spectator
git reset filename.txt

Se eliminará un archivo llamado filename.txt del índice actual, el área "a punto de comprometerse", sin cambiar nada más.

9
Rahul Sinha

En SourceTree puedes hacerlo fácilmente a través de la interfaz gráfica de usuario. Puede verificar qué comando usa sourcetree para desestabilizar un archivo.

Creé un nuevo archivo y lo agregué a git. Luego lo desestabilizé usando la interfaz gráfica de SourceTree. Este es el resultado:

Archivos sin etapas [12/08/15 10:43]
git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetree reset -q - ruta/a/archivo/filename.Java

SourceTree usa reset para descomponer archivos nuevos.

8
miva2
git reset filename.txt  

Se eliminará un archivo llamado filename.txt del índice actual, el área "a punto de comprometerse", sin cambiar nada más.

7
Joseph Mathew

Una de las soluciones más intuitivas es usar SourceTree .

Solo puede arrastrar y soltar archivos desde y sin etapas  enter image description here

7
Marcin Szymczak

El comando git reset lo ayuda a modificar el área de preparación o el área de preparación y el árbol de trabajo. La capacidad de Git para elaborar compromisos exactamente como usted quiere significa que a veces necesita deshacer cambios en los cambios que realizó con git add.

Puedes hacerlo llamando a git reset HEAD <file to change>. Tienes dos opciones para deshacerte completamente de los cambios. git checkout HEAD <file(s) or path(s)> es una forma rápida de deshacer los cambios en su área de preparación y en el árbol de trabajo. Tenga cuidado con este comando, sin embargo, porque elimina todos los cambios en su árbol de trabajo. Git no conoce esos cambios ya que nunca se han cometido. No hay forma de recuperar esos cambios una vez que ejecute este comando.

Otro comando a su disposición es git reset --hard. Es igualmente destructivo para su árbol de trabajo: cualquier cambio no confirmado o cambios por etapas se pierden después de ejecutarlo. Ejecutar git reset -hard HEAD hace lo mismo que git checkout HEAD. Simplemente no requiere un archivo o ruta para trabajar.

Puedes usar --soft con git reset. Restaura el repositorio a la confirmación que especifique y realiza todas las modificaciones. Los cambios que ya haya realizado no se verán afectados, ni los cambios en su árbol de trabajo.

Finalmente, puede usar --mixed para restablecer el árbol de trabajo sin realizar cambios en la clasificación. Esto también elimina cualquier cambio que esté en escena.

1
SAIguru011