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.
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á).
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:
git init
git add .
git status
... un montón de rollos de basura por ...
=> Maldita sea, no quería añadir todo eso.
google "undo git add"
=> encontrar Desbordamiento de pila - yay
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).
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)
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
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>
:
Si <file>
fue no rastreado previamente , git add
lo agrega al caché , con su contenido actual.
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)
git rm --cached . -r
"anulará" todo lo que ha agregado de su directorio actual de forma recursiva
Correr
git gui
y elimine todos los archivos manualmente o seleccionándolos todos y haciendo clic en el botón unstage from commit .
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 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:
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>
La pregunta no está planteada claramente. La razón es que git add
tiene dos significados:
git rm --cached file
.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
Si está en su confirmación inicial y no puede usar git reset
, simplemente declare "Git quiebra", elimine la carpeta .git
y comience
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
git remove
o git rm
se pueden utilizar para esto, con el indicador --cached
. Tratar:
git help rm
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)
$
Aquí hay una manera de evitar este problema desconcertante al iniciar un nuevo proyecto:
git init
.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:
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.
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)
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.
Para restablecer cada archivo en una carpeta particular (y sus subcarpetas), puede usar el siguiente comando:
git reset *
use el comando *
para manejar múltiples archivos a la vez
git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*
etc
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.
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.
Para deshacer git añadir uso
git reset filename
Este comando deshará tus cambios:
git reset HEAD filename.txt
También puedes usar
git add -p
para añadir partes de archivos.
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 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á
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.
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.
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.
Una de las soluciones más intuitivas es usar SourceTree .
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.