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


Incorrectamente agregué archivos a git usando el comando:

git add myfile.txt

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


Hasta el momento hay 48 respuestas (algunas eliminadas). No agregue uno nuevo a menos que tenga alguna información nueva.


7450
2017-12-07 21:57


origen


Respuestas:


Puedes deshacer git add antes de comprometerse con

git reset <file>

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

Puedes usar

git reset

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

En 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 commit en su repositorio) o es ambiguo (porque creó una rama llamada HEAD, que es una cosa estúpida que no deberías hacer). Esta fue cambiado en Git 1.8.2, sin embargo, en las versiones modernas de Git puedes usar los comandos anteriores incluso antes de realizar tu primer commit:

"git reset" (sin opciones o parámetros) utilizado para error cuando      no tienes compromisos en tu historial, pero ahora te da      un índice vacío (para que coincida con una confirmación inexistente, ni siquiera está activado).


8357
2017-12-07 22:30



Usted quiere:

git rm --cached <added_file_to_undo>

Razonamiento:

Cuando era nuevo esto, primero intenté

git reset .

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

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

Resulta que esto se debe a que HEAD ref (branch?) No existe hasta después del primer commit. Es decir, te encontrarás con el mismo problema de principiante que yo si tu flujo de trabajo, como el mío, fuera algo así como:

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

    ... muchas perversidades por ...

    => Maldición, no quería agregar todo eso.

  5. google "undo git add"

    => encontrar Stack Overflow - yay

  6. git reset .

    => fatal: Error al resolver 'HEAD' como una referencia válida.

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

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

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

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

Tenga en cuenta las advertencias en otro lugar aquí - git rm borra su copia de trabajo local del archivo, pero no si utiliza - caché. Este es el resultado de git help rm:

- caché       Utilice esta opción para eliminar y eliminar trazados solo del índice.       Los archivos de árbol de trabajo, ya sean modificados o no, serán dejados.

Procedo a usar

git rm --cached .

para eliminar todo y comenzar de nuevo. No funcionó, porque mientras add . es recursivo, resulta rm necesariamente -r recurse. Suspiro.

git rm -r --cached .

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

git add -n .

Cerré todo en un lugar seguro antes de confiar git help rm acerca de --cached no destruir nada (y qué pasa si lo escribí mal).


1950
2018-03-25 16:20



Si escribe:

git status

git te dirá lo que está organizado, etc., incluidas las instrucciones sobre cómo desestabilizar:

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

Me parece que git hace un buen trabajo empujándome para 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)

484
2017-12-07 23:22



Para aclarar: git add mueve los cambios desde el directorio de trabajo actual al área de ensayo (índice).

Este proceso se llama puesta en escena. Entonces el comando más natural para escenario los cambios (archivos modificados) son obvios:

git stage

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

Lástima que no hay git unstage ni git unadd comandos. 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 utilizo alias más cortos:

git a #for staging
git u #for unstaging

220
2017-09-10 20:28



Una adición a la respuesta aceptada, si su archivo agregado erróneamente fue enorme, probablemente notará que, incluso después de eliminarlo del índice con 'git reset', todavía parece ocupar espacio en el .git directorio. Esto no es nada preocupante, el archivo de hecho todavía está en el repositorio, pero solo como un "objeto suelto", no se copiará a otros repositorios (mediante clonación, inserción), y el espacio será eventualmente reclamado, aunque quizás no muy pronto Si estás ansioso, puedes correr:

git gc --prune=now

Actualizar (Lo que sigue es mi intento de despejar la confusión que puede surgir de las respuestas más votadas):

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

git reset HEAD <file> ?

o

git rm --cached <file>?

Estrictamente hablando, y si no me equivoco: ninguna.

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

Recordemos primero qué git add <file> en realidad lo hace:

  1. Si <file> estaba no rastreado previamente, git add  lo agrega a la memoria caché, con su contenido actual.

  2. Si <file> estaba ya rastreado, git add  guarda el contenido actual (instantánea, versión) a la memoria caché. En GIT, esta acción todavía se llama añadir, (no mera actualizar it), porque dos versiones diferentes (instantáneas) de un archivo se consideran dos elementos diferentes: por lo tanto, de hecho estamos agregando un nuevo elemento a la caché, para eventualmente enviarlo más tarde.

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

Incorrectamente agregué archivos usando el comando ...

El escenario del PO 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 correr git rm --cached <file>.

Y también podríamos correr git reset HEAD <file>. En general, esto es preferible, porque funciona en ambos escenarios: también lo hace cuando añadimos 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 does: un nuevo repositorio (sin commits). Pero, realmente, 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 equivocado git add sobrescribió una versión anterior no confirmada por etapas, 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 crítico si solo seguimos el flujo de trabajo perezoso habitual de hacer 'git add' solo para agregar nuevos archivos (caso 1), y actualizamos los nuevos contenidos a través de la confirmación, git commit -a mando.


136
2018-05-18 18:05



git rm --cached . -r

"des-agregará" todo lo que ha agregado de su directorio actual recursivamente


85
2017-12-09 21:19



correr

git gui

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


77
2017-10-12 01:12



Git tiene comandos para cada acción imaginable, pero necesita un amplio conocimiento para hacer las cosas bien y, por lo tanto, es contrario a la intuición en el mejor de los casos ...

Lo que hiciste antes:

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

Lo que quieras:

  • Elimine el archivo del índice, pero manténgalo actualizado y déjelo sin cambios confirmados 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:

    # 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 git reset --hard HEAD no funcionará con archivos individuales.

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

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

    git rm <file>
    

73
2018-03-29 11:14