git - todos - quitar un archivo de commit
¿Cómo deshacer ''git add'' antes de confirmar? (30)
Aquí hay una manera de evitar este problema desconcertante al iniciar un nuevo proyecto:
- Crea el directorio principal para tu nuevo proyecto.
- Ejecutar
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 el git reset
Git si no tienes ningún commit. Si creas una pequeña confirmación inicial solo por tener una, luego puedes git add -A
y git reset
tantas veces como quieras 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.
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.
Este comando deshará tus cambios:
git reset HEAD filename.txt
También puedes usar
git add -p
para añadir partes de archivos.
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:
- Cambié un archivo y usé
git add .
, ogit 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 las 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:
- agregando un nuevo archivo al área de preparación, luego deshaga con
git rm --cached file
. - agregando un archivo modificado al área de preparación, luego deshaga con
git reset HEAD file
.
en caso de duda, utilizar
git reset HEAD file
Porque hace lo esperado en ambos casos.
Advertencia: si git rm --cached file
en un archivo que se modificó (un archivo que existía anteriormente en el repositorio), ¡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
te dirá si el archivo fue nuevo 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
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.
Para aclarar: git add
mueve los cambios desde el 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 organizar los cambios (archivos modificados) es el obvio:
git stage
git add
es solo un alias más fácil de escribir para la git stage
Lástima que no haya 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
Para deshacer git añadir uso
git reset filename
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 nuevos archivos añadidos accidentalmente.
Para restablecer cada archivo en una carpeta particular (y sus subcarpetas), puede usar el siguiente comando:
git reset *
Puedes 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 ninguna confirmación en su repositorio) o es ambiguo (porque creó una rama llamada HEAD
, que es una cosa estúpida que no debes hacer). Sin embargo, esto se cambió en Git 1.8.2 , por lo que en las versiones modernas de Git puede usar los comandos anteriores incluso antes de realizar su primer confirmación:
"git reset" (sin opciones o parámetros) se utiliza para errores cuando no tiene ninguna confirmación en su historial, pero ahora le da un índice vacío (para coincidir con la confirmación inexistente en la que ni siquiera está).
Según muchas de las otras respuestas, puede utilizar git reset
PERO:
Encontré esta gran 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
Si escribe:
git status
git le dirá lo que está en escena, etc., incluidas las instrucciones sobre cómo anular el escenario:
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)
Si está en su confirmación inicial y no puede usar git reset, simplemente declare "Git quiebra", elimine la carpeta .git y comience de nuevo.
Simplemente teclea git reset
, volverá atrás y es como si nunca hubieras escrito git add .
Desde tu último compromiso. Asegúrate de que has cometido antes.
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)
Una adición a la respuesta aceptada, si su archivo agregado por error fue enorme, probablemente notará que, incluso después de eliminarlo del índice con '' git reset
'', todavía parece ocupar 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, inserción), y el espacio se recuperará eventualmente, aunque Quizás no muy pronto. Si estás ansioso, puedes correr:
git gc --prune=now
Actualización (lo que sigue es mi intento de aclarar algunas confusiones que pueden 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>
?
Hablando estrictamente, y si no me equivoco: ninguno .
git add
no se puede deshacer , de forma segura, en general.
Recordemos primero lo que git add <file>
realmente hace:
Si no se realizó el seguimiento de
<file>
,git add
agrega al caché , con su contenido actual.Si ya se realizó el seguimiento de
<file>
,git add
guarda el contenido actual (instantánea, versión) en el caché. En GIT, esta acción aún se llama agregar , (no solo actualizarla ), porque dos versiones diferentes (instantáneas) de un archivo se consideran como dos elementos diferentes: por lo tanto, de hecho, estamos agregando un nuevo elemento a la memoria caché, que finalmente será comprometido 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ñaló en la respuesta) solo un escenario en el que git reset HEAD
no funciona, pero git rm --cached
sí git rm --cached
hace: un nuevo repositorio (sin confirmación). 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
equivocado git add
una versión sobrescrita de una versión anterior no comprometida, no podemos recuperarla. Por eso, 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 nuevos archivos (caso 1), y actualizamos los nuevos contenidos mediante el comando commit, git commit -a
.
* (Edición: lo anterior es prácticamente correcto, pero aún puede haber algunas formas ligeramente intrincadas / complicadas para recuperar cambios que se realizaron, pero no se confirmaron y luego se sobrescribieron, consulte los comentarios de Johannes Matokic y iolsmit)
Use 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)
$
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 el 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:
- cd a mi gran directorio de nuevos proyectos para probar Git, el nuevo hotness
-
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 la solución de hecho es usar 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 utiliza --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. No funcionó, sin embargo, porque mientras se add .
Es recursivo, resulta rm
necesidades -r
para recursionar. Suspiro.
git rm -r --cached .
Está 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 que --cached
me --cached
el " --cached
no destruyera nada (y si lo --cached
mal).
correr
git gui
y elimine todos los archivos de forma manual o seleccionándolos todos y haciendo clic en el botón para cancelar la fase de confirmación .
use el comando *
para manejar múltiples archivos a la vez
git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*
etc
git add myfile.txt
# esto agregará su archivo a la lista de confirmaciones
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. Entonces, si tu cabeza no lo tiene, significa que simplemente lo restablecerá.
git remove
o git rm
se pueden usar para esto, con el indicador --cached
. Tratar:
git help rm
Deshacer un archivo que ya se agregó es bastante fácil con git , para restablecer myfile.txt
que ya se agregó, use:
git reset HEAD myfile.txt
Explique:
Una vez que haya preparado los archivos no deseados, para deshacerlos, puede hacer git reset
, Head
es la cabeza 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:
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: el proceso de pago cambia el código de los archivos y pasa al último estado actualizado (confirmado). restablecer no cambia los códigos; simplemente restablece el encabezado.
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 utiliza reset
para desestabilizar nuevos archivos.
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.
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.
git rm --cached . -r
"anulará" todo lo que ha agregado de su directorio actual de forma recursiva