git - tag - Cómo desmarcar gran cantidad de archivos sin borrar el contenido
revertir cambios en un archivo git (8)
git reset
Si todo lo que quieres es deshacer una ejecución "git add" demasiado entusiasta:
git reset
Sus cambios no estarán en fase y estarán listos para que los vuelva a agregar a su gusto.
NO git reset --hard
.
No solo desestabilizará los archivos agregados, sino que revertirá cualquier cambio que haya realizado en su directorio de trabajo. Si creó algún archivo nuevo en el directorio de trabajo, no los eliminará.
Accidentalmente agregué muchos archivos temporales usando git add -A
Logré desarreglar los archivos usando 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 si alguien pudiera explicar cómo funciona esta operación de tubería.
Me temo que la primera de esas líneas de comando eliminó incondicionalmente de la copia de trabajo todos los archivos que se encuentran en el área de preparación de git. El segundo eliminó todos los archivos que fueron rastreados pero que ahora han sido eliminados. Desafortunadamente, esto significa que habrá perdido cualquier modificación no confirmada de esos archivos.
Si desea obtener su copia de trabajo e índice de nuevo a cómo estaban en el último compromiso , puede (con cuidado ) usar el siguiente comando:
git reset --hard
Digo "cuidadosamente" desde que git reset --hard
borrará los cambios no confirmados en su copia de trabajo e índice. Sin embargo, en esta situación, suena como si solo quisiera volver al estado en su último compromiso, y los cambios no confirmados se han perdido de todos modos.
Actualización: de sus comentarios sobre la respuesta de Amber se desprende que aún no ha creado ningún compromiso (ya que HEAD no se puede resolver), por lo que esto no ayudará, me temo.
En cuanto a cómo funcionan esos conductos: git ls-files -z
y git diff --name-only --diff-filter=D -z
ambos git diff --name-only --diff-filter=D -z
una lista de nombres de archivos separados con el byte 0
. (Esto es útil, ya que, a diferencia de las nuevas líneas, se garantiza que 0
bytes no aparecerán en los nombres de archivo en sistemas similares a Unix). El final de la línea de comando. La opción -0
dice que esperar una entrada estándar separada por 0
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:
hello
goodbye
hello again
... entonces el comando xargs echo whatever < test.txt
invocará el comando:
echo whatever hello goodbye hello again
Si HEAD no está configurado, también puedes hacer
git rm -rf --cached .
para desmarcar todo. Esto es efectivamente lo mismo que la solución de Sehe, pero evita mezclarse con los internos de Git.
Si desea eliminar todas las modificaciones, utilice el comando siguiente,
git reset --soft HEAD
En el caso de que desee anular los cambios y revertirlos desde el directorio de trabajo,
git reset --hard HEAD
Si tiene un repo prístino (o HEAD no está configurado) [1] simplemente podría
rm .git/index
Por supuesto, esto requerirá que vuelva a agregar los archivos que deseaba agregar.
[1] Nota (como se explica en los comentarios) esto generalmente solo ocurre cuando el repositorio es completamente nuevo ("pristine") o no se han realizado confirmaciones. Más técnicamente, siempre que no haya checkout o work-tree.
Jus dejándolo más claro :)
Use git reset HEAD
para restablecer el índice sin eliminar archivos. (Si solo desea restablecer un archivo en particular en el índice, puede usar git reset HEAD -- /path/to/file
para hacerlo).
El operador de tubería, en una concha, toma la salida stdin
del proceso a la izquierda y lo pasa como stdin
al proceso a la derecha. Es esencialmente el equivalente de:
$ proc1 > proc1.out
$ proc2 < proc1.out
$ rm proc1.out
pero en cambio es $ proc1 | proc2
$ proc1 | proc2
, el segundo proceso puede comenzar a obtener datos antes de que el primero $ proc1 | proc2
, y no hay un archivo real involucrado.
Advertencia: no utilice el siguiente comando a menos que desee perder el trabajo no confirmado.
El uso de git reset
ha sido explicado, pero también solicitó una explicación de los comandos canalizados, así que aquí va:
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
El comando git ls-files
enumera todos los archivos que git conoce. La opción -z
impone un formato específico en ellos, el formato esperado por xargs -0
, que luego invoca rm -f
en ellos, 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 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 sin etapas; Los archivos que has cambiado pero que aún no has confirmado. La opción --name-only
significa que desea que los nombres de archivo (completos) solo y --diff-filter=D
significa que está interesado solo en archivos eliminados. (Oye, ¿no acabamos de eliminar un montón de cosas?) Esto luego se canaliza a los xargs -0
que vimos antes, lo que invoca a git rm --cached
en ellos, lo que significa que se eliminan del caché, mientras que el el árbol se debe dejar 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, en etapas o sin etapas, desaparecen y su árbol de trabajo está vacío. Grita, revisa tus archivos desde el origen o el control remoto, y rehacer tu trabajo. Maldiga al sádico que escribió estas líneas infernales; No tengo ni idea de por qué alguien querría hacer esto.
TL; DR: acabas de hose todo; comienza de nuevo y usa git reset
desde ahora.
git stash && git stash pop