Accidentalmente agregué muchos archivos temporales usando git add -A
Logré desestadificar los archivos con los siguientes comandos y logré eliminar el índice sucio.
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
Los comandos anteriores se enumeran en el git help rm
. Pero lamentablemente, mis archivos también se eliminaron en la ejecución, a pesar de que había dado la opción de caché. ¿Cómo puedo borrar el índice sin perder el contenido?
También sería útil que alguien pueda explicar cómo funciona esta operación de tubería.
git
version-control
sarat
fuente
fuente
rm -f
no es un comando git y no tiene una--cached
opción. Sus archivos locales se eliminaron antes de ejecutarlos,git rm
así que no creo que pueda culpar legítimamentegit rm
de nada.git reset --hard
que no es la respuesta correcta y, de hecho, eliminará el contenido. Esto confundirá a los usuarios, como a mí.Respuestas:
git reset
Si todo lo que quiere es deshacer una ejecución excesivamente entusiasta de "git add":
Sus cambios no estarán organizados y estarán listos para que los vuelva a agregar a su gusto.
No ejecute
git reset --hard
.No solo desestabilizará sus archivos agregados, sino que revertirá cualquier cambio que haya realizado en su directorio de trabajo. Sin embargo, si creó archivos nuevos en el directorio de trabajo, no los eliminará.
fuente
git checkout -- *
tambiénSi tiene un repositorio prístino (o HEAD no está configurado) [1] simplemente podría
Por supuesto, esto requerirá que volver a añadir los archivos que qué desea ser agregado.
[1] Nota (como se explica en los comentarios), esto generalmente solo sucedería cuando el repositorio sea nuevo ("prístino") o si no se han realizado compromisos. Más técnicamente, siempre que no haya pago o árbol de trabajo.
Solo haciéndolo más claro :)
fuente
Use
git reset HEAD
para restablecer el índice sin eliminar archivos. (Si solo desea restablecer un archivo en particular en el índice, puedegit reset HEAD -- /path/to/file
hacerlo).El operador de tubería, en una carcasa, toma el
stdout
proceso a la izquierda y lo pasastdin
al proceso a la derecha. Es esencialmente el equivalente de:pero en su lugar
$ proc1 | proc2
, el segundo proceso puede comenzar a obtener datos antes de que el primero termine de generarlos, y no hay ningún archivo real involucrado.fuente
git reset HEAD
sin especificar nada más y restablecerá todo el índice. Luego, puede volver a agregar solo los archivos que desee.$ git reset HEAD fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Use '--' to separate paths from revisions
git reset
ese momento, sin elHEAD
.$ git reset fatal: Failed to resolve 'HEAD' as a valid ref.
fuente
Si HEAD no está configurado (es decir, aún no tiene confirmaciones, pero no desea simplemente volar
.git
porque ya ha configurado otra configuración de repositorio que desea mantener), también puede hacerlopara destrabar todo. Esto es efectivamente lo mismo que la solución de Sehe, pero evita la intrusión con los componentes internos de Git.
fuente
.git
porque ha configurado otra configuración de repositorio que querer guardar. He editado para aclarar esto.Advertencia: ¡no use el siguiente comando a menos que quiera perder el trabajo no comprometido!
El uso
git reset
se ha explicado, pero también solicitó una explicación de los comandos canalizados, así que aquí va:El comando
git ls-files
enumera todos los archivos que git conoce. La opción les-z
impone un formato específico, el formato esperado por ellosxargs -0
, que luego los invocarm -f
, lo que significa eliminarlos sin verificar su aprobación.En otras palabras, "enumere todos los archivos que Git conoce y elimine su copia local".
Luego llegamos a
git diff
, que muestra los cambios entre las diferentes versiones de elementos que Git conoce. Esos pueden ser cambios entre diferentes árboles, diferencias entre copias locales y copias remotas, etc.Tal como se usa aquí, muestra los cambios no organizados; los archivos que ha cambiado pero que aún no ha confirmado. La opción
--name-only
significa que solo desea los nombres de archivo (completos) y--diff-filter=D
significa que solo está interesado en los archivos eliminados. (Oye, ¿no acabamos de eliminar un montón de cosas?) Esto luego se canaliza a loxargs -0
que vimos antes, lo que invocagit rm --cached
en ellas, lo que significa que se eliminan del caché, mientras que el árbol de trabajo debe dejarse solo, excepto que acaba de eliminar todos los archivos de su árbol de trabajo. Ahora también se eliminan de su índice.En otras palabras, todos los cambios, realizados o no, han desaparecido y su árbol de trabajo está vacío. Llora, revisa tus archivos desde el origen o de forma remota, y vuelve a hacer tu trabajo. Maldice al sádico que escribió estas líneas infernales; No tengo idea de por qué alguien querría hacer esto.
TL; DR: acabas de limpiar todo; comenzar de nuevo y usar
git reset
de ahora en adelante.fuente
Me temo que la primera de esas líneas de comando eliminó incondicionalmente de la copia de trabajo todos los archivos que están en el área de preparación de git. El segundo eliminó todos los archivos que se rastrearon pero que ahora se han eliminado. Desafortunadamente, esto significa que habrá perdido cualquier modificación no confirmada de esos archivos.
Si desea que su copia de trabajo e índice vuelvan a estar como estaban en la última confirmación , puede ( cuidadosamente ) usar el siguiente comando:
Digo "cuidadosamente", ya
git reset --hard
que eliminará los cambios no confirmados en su copia de trabajo e índice. Sin embargo, en esta situación parece que solo desea volver al estado en su última confirmación, y los cambios no confirmados se han perdido de todos modos.Actualización: según sus comentarios sobre la respuesta de Amber, todavía no ha creado ninguna confirmación (ya que HEAD no se puede resolver), por lo que esto no ayudará, me temo.
En cuanto a cómo funcionan esas canalizaciones:
git ls-files -z
ygit diff --name-only --diff-filter=D -z
ambas generan una lista de nombres de archivo separados con el byte0
. (Esto es útil, ya que, a diferencia de las nuevas líneas,0
se garantiza que los bytes no aparezcan en los nombres de archivo en sistemas similares a Unix). El programaxargs
esencialmente construye líneas de comando a partir de su entrada estándar, de forma predeterminada al tomar líneas de entrada estándar y agregarlas al final de la línea de comando. La-0
opción dice esperar entrada estándar a separada por0
bytes.xargs
puede invocar el comando varias veces para usar todos los parámetros de la entrada estándar, asegurándose de que la línea de comando nunca sea demasiado larga.Como ejemplo simple, si tiene un archivo llamado
test.txt
, con los siguientes contenidos:... entonces el comando
xargs echo whatever < test.txt
invocará el comando:fuente
Si desea eliminar todos los cambios, use el siguiente comando,
En el caso de que desee eliminar los cambios del escenario y revertirlos desde el directorio de trabajo,
fuente