Cómo eliminar múltiples archivos eliminados en el repositorio de Git

237

He eliminado algunos archivos y el estado de git se muestra a continuación.

Me he comprometido y empujado.

GitHub todavía muestra los archivos eliminados en el repositorio. ¿Cómo puedo eliminar archivos en el repositorio de GitHub?

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    modules/welcome/language/english/kaimonokago_lang.php
#   deleted:    modules/welcome/language/french/kaimonokago_lang.php
#   deleted:    modules/welcome/language/german/kaimonokago_lang.php
#   deleted:    modules/welcome/language/norwegian/kaimonokago_lang.php

Si lo uso git rm, da lo siguiente.

usage: git rm [options] [--] <file>...

-n, --dry-run         dry run
-q, --quiet           do not list removed files
--cached              only remove from the index
-f, --force           override the up-to-date check
-r                    allow recursive removal
--ignore-unmatch      exit with a zero status even if nothing matched
espinilla
fuente

Respuestas:

638
git add -u 

actualiza todos tus cambios

mshameers
fuente
31
Funciona un encanto. Cuando vea algo como "estado de git | sed -n '/ ^ # * eliminado: / s /// p' | xargs git rm" como una solución propuesta para un requisito tan simple pero frecuente, entonces sabe que una solución mejor es, o pronto lo estará, a la vuelta de la esquina.
arcseldon el
simple es mejor, esto es realmente útil, entonces la manera "bash"
castiel
1
El autor pregunta cómo eliminar archivos, ¿por qué agregar archivos es la respuesta correcta?
kelin
3
@kelin: de git docs ( git-scm.com/docs/git-add ): "-u --update Actualiza el índice justo donde ya tiene una entrada que coincide con <pathspec>. Esto elimina y modifica las entradas de índice a coincide con el árbol de trabajo, pero no agrega archivos nuevos. Si no se proporciona <pathspec> cuando se usa la opción -u, se actualizan todos los archivos rastreados en todo el árbol de trabajo (las versiones antiguas de Git se usan para limitar la actualización al directorio actual y sus subdirectorios) ".
HEDMON
92

Ten mucho cuidado git rm .; puede eliminar más de lo que quieres. Por supuesto, puede recuperarse, pero es más sencillo no tener que hacerlo.

Más simple sería:

git rm modules/welcome/language/english/kaimonokago_lang.php \
       modules/welcome/language/french/kaimonokago_lang.php \
       modules/welcome/language/german/kaimonokago_lang.php \
       modules/welcome/language/norwegian/kaimonokago_lang.php

No puede usar comodines de shell porque los archivos no existen, pero podría usar (al menos en Bash):

git rm modules/welcome/language/{english,french,german,norwegian}/kaimonokago_lang.php

O considere:

git status | sed -n '/^# *deleted:/s///p' | xargs git rm

Esto toma la salida de git status, no imprime nada por defecto ( sed -n), pero en las líneas que comienzan # deleted:, elimina el #y el deleted:y imprime lo que queda; xargsreúne los argumentos y los proporciona a un git rmcomando. Esto funciona para cualquier número de archivos, independientemente de la similitud (o diferencia) en los nombres.

Jonathan Leffler
fuente
66
Usted puede utilizar comodines (aunque puede que tenga que escapar de ellos), y git coincidirán con las rutas en el índice, no sólo aquellos en el árbol de trabajo, por lo que no importa que no existen en el sistema de archivos.
Ben James
109
git diff --diff-filter=D --name-only -z | xargs -0 git rmes un enfoque más confiable que intentar analizar, git statusque está orientado al usuario y no se garantiza que sea estable en futuras versiones.
CB Bailey
@Charles: eso es ciertamente mejor, pero requiere bastante conocimiento sobre qué opciones están disponibles git diff(que no tenía, ya que no había tenido la necesidad antes). ¡Gracias!
Jonathan Leffler
8
Tenga en cuenta que también hay "git ls-files --deleted"
Petr Gladkikh
1
entonces, git ls-files --deleted | xargs git rmhizo el truco para mí.
fiacobelli
50

Otra versión de la respuesta de ByScripts es

git rm $(git ls-files --deleted)

Esto SOLO eliminará los archivos eliminados del git.

También podría usarse para agregar SOLAMENTE archivos modificados también.

git add $(git ls-files --modified)

Estos comandos también funcionan en gitbash para windows.

Vijay C
fuente
2
No tiene precio, el git ls-filesestado con eliminado o modificado es muy útil.
Mario Peshev
1
El comportamiento de 'git add --update (or -u)'sin argumento de ruta desde un subdirectorio del árbol cambiará en Git 2.0 y ya no debería usarse. Para agregar contenido para todo el árbol, ejecute: git add --update :/ (o git add -u: /) Para restringir el comando al directorio actual, ejecute: git add --update . (o git add -u.) Con la versión actual de Git, el comando está restringido a directorio actual
Ans
1
¿Alguna idea de cómo manejar caminos con espacios en ellos? Ejemplo: src/my spaced directory/myfile. Esto se puede manejar individualmente, pero ¿cómo se puede manejar usando los comandos de esta respuesta?
Muhammad Gelbana
35

Actualice todos los cambios que realizó:

git add -u

Los archivos eliminados deben cambiar de no en escena (generalmente de color rojo) a en escena (verde). Luego, comprométase a eliminar los archivos eliminados:

git commit -m "note"
Aziz Alto
fuente
1
Se merece la insignia populista.
Juan
1
Esta es, con mucho, la mejor solución. Sin hacks de secuencias de comandos, sin procesos largos, solo una bandera para decirle a git que actualice su índice a fondo.
Ron Dahlgren
¡Brillante! Me salvó de tener que escribir más de 20 rutas de archivos. ¡Gracias!
allardbrain
12

La mejor solución si no le importa organizar archivos modificados es usarlo git add -ucomo dicen mshameers y / o pb2q .

Si solo desea eliminar los archivos eliminados, pero no realizar ninguna modificación, creo que debería usar el ls-filesargumento con la --deletedopción (no es necesario usar expresiones regulares u otras opciones / argumentos complejos):

git ls-files --deleted | xargs git rm
ByScripts
fuente
1
git add -Aresuelve este problema ... solo en caso de que alguien quiera saber en el futuro. compruebe la respuesta a continuación
Ja8zyjits
8

Sí, git rm <filename>organizará el estado eliminado de un archivo, donde <filename>podría haber un patrón global:

$ git rm modules/welcome/language/*/kaimonokago_lang.php
rm modules/welcome/language/english/kaimonokago_lang.php
rm modules/welcome/language/french/kaimonokago_lang.php
rm modules/welcome/language/german/kaimonokago_lang.php
rm modules/welcome/language/norwegian/kaimonokago_lang.php

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    modules/welcome/language/english/kaimonokago_lang.php
#       ...

Entonces, puedes comprometerte.

git commit -a hará esto de una vez, si quieres.

También puede usar git add -upara organizar todos los cambios, incluidos todos los archivos eliminados, y luego confirmar.

Ben James
fuente
entonces rm. (punto final) ¿eliminarlos de una vez?
shin
¿Entonces solo git rm eliminará todo de una vez?
Shin
1
Puede usar un patrón de estilo glob para eliminar múltiples archivos; Actualicé mi respuesta para mostrar un ejemplo.
Ben James
55
Parece que git add -ues exactamente lo que estamos buscando: si realiza muchas eliminaciones, entonces desea confirmar todas las eliminaciones, esa parece ser la forma más fácil y `` estándar '' (es decir, sin globos específicos de casos o análisis de shell complejos en xargs). ¿Hay alguna razón por la que no quisiéramos usar esto, aparte del hecho de que agrega todos los cambios a la vez?
trisweb
7

Cuando tengo muchos archivos que he eliminado que no están organizados para la confirmación, puedes git rmverlos en un solo programa con:

for i in `git status | grep deleted | awk '{print $3}'`; do git rm $i; done

Como se mencionó en la pregunta, tenga cuidado con git rm.

Justin Mandzik
fuente
5

Prueba esto:

 git rm `git ls-files -d`
eludom
fuente
Esto resolvió mi problema de organizar solo scripts eliminados (usando bash)
Mariano Argañaraz
3

Puedes usar

git commit -m "remove files" -a
git push

Después de haber eliminado archivos manualmente.

onalbi
fuente
1
O de manera idéntica pero más sucinta: git commit -am "eliminar archivos"
BradChesney79
3

Puede crear un script de shell que eliminará todos sus archivos cuando se ejecute:

git status | grep deleted | awk '{print "git rm " $3;}' > ../remove.sh

El script que se crea es remove.shy contiene la lista completa de git rmcomandos.

La comadreja
fuente
2
git status | sed 's/^#\s*deleted:\s*//' | sed 's/^#.*//' | xargs git rm -rf
Boush
fuente
2
git add -u .

git add --update .
Euccas
fuente
2

Si desea eliminarlos todos usando "git rm". Esto es lo que hago:

git ls-files --deleted -z | xargs -0 git rm

Esta consulta enumera todos los archivos que se han eliminado y los elimina del repositorio de git. Espero eso ayude.

DevWL
fuente
1

La función de limpieza integrada también puede ser útil ...

git clean -fd
Randall Borck
fuente
1
Esto solo se aplica a los archivos no rastreados.
Elijah Lynn
1

¡Tuve este problema de archivos fantasmas que aparecen en mi repositorio después de que los eliminé y encontré este comando ordenado!

git add -A

Es esencialmente igual git add -ay git add -ucombinado, pero distingue entre mayúsculas y minúsculas. Lo obtuve de este increíble enlace (este enlace apunta a la versión en archive.org ahora, porque el original se ha convertido en una página de spam / phishing a partir de junio de 2016)

NetOperator Wibby
fuente
0

Aquí se explica cómo detectar archivos eliminados y organizar su eliminación como parte de la próxima confirmación. Todas las soluciones en este hilo tienen diferentes méritos. Esta solución a continuación trata específicamente el problema de los nombres de archivos con espacios en ellos.

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm '{}'

asegúrese de probar esto con la opción --dry-run de git antes de ejecutarlo con lo siguiente:

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm --dry-run '{}'

explicación:

git status --porcelain

Esto imprime algo como D "/ ruta a una carpeta / ruta a un archivo" que ocurre solo cuando hay espacios en los nombres de ruta

awk '/^.D .*$/ {print $0}'

solo coincide con las líneas que comienzan con "D"

sed 's/ D \(.*\)/\1/'

eliminar "D" del frente de cada cadena

tr -d '"'

eliminar comillas, si las hay

xargs -I {} git rm '{}'

defina las variables de nombre de archivo como {} ejecute el nombre del archivo en git rm entre comillas simples para asegurarse de que admite nombres de archivos con espacios.

DAKOTA DEL NORTE
fuente