¿Cómo eliminar los archivos que se enumeran en el .gitignore pero aún en el repositorio?

327

Tengo algunos archivos en mi repositorio que deben ignorarse, los agregué a .gitignore pero, por supuesto, no se eliminan de mi repositorio.

Entonces, mi pregunta es, ¿hay algún comando o script mágico que use filter-branch que pueda reescribir mi historial y eliminar todos estos archivos fácilmente? ¿O simplemente un comando que creará una confirmación que los eliminará?

Intrepidd
fuente
3
El duplicado del archivo .gitignore no se ignora
ADVERTENCIA: Si bien esto no eliminará el archivo físico de su local, eliminará los archivos de otras máquinas de desarrolladores en el próximo git pull. ¿Cómo hacer que Git "se olvide" de un archivo que fue rastreado pero ahora está en .gitignore?
Kris Roofe
@Stevoisiak esto no es un duplicado de esa pregunta porque esta pregunta sobre TODOS los archivos ignorados y también tiene una mejor respuesta que cualquiera de las preguntas similares.
Omn

Respuestas:

438

Puede eliminarlos del repositorio manualmente:

git rm --cached file1 file2 dir/file3

O, si tiene muchos archivos:

git rm --cached `git ls-files -i --exclude-from=.gitignore`

Pero esto no parece funcionar en Git Bash en Windows. Produce un mensaje de error. Lo siguiente funciona mejor:

git ls-files -i --exclude-from=.gitignore | xargs git rm --cached  

Con respecto a reescribir toda la historia sin estos archivos, dudo mucho que haya una forma automática de hacerlo.
Y todos sabemos que reescribir la historia es malo, ¿no? :)

Samy Dindane
fuente
2
Desafortunadamente, el comando Git Bash en Windows no funciona con rutas que contienen espacios
Nate Bundy
19
@ Cupcake gracias. git ls-files -i -z --exclude-from=.gitignore | xargs -0 git rm --cachedparece hacer el truco
Nate Bundy
3
Me quedé atascado con el mismo problema en Windows. Estoy usando powershell, y en mi caso recibí el tercer comando indicado por @ samy-dindane y lo cambié a un foreach. Se convirtió en estogit ls-files -i --exclude-from=.gitignore | %{git rm --cached $_}
digaomatias
1
"git ls-files -i --exclude-from = .gitignore" es muy útil, me dice qué archivos están excluidos por .ignore.
Owen Cao
1
Me alegré de encontrar estos comandos, PERO en realidad no elimina los archivos del repositorio. Cuando eliminé 2300 kB de imágenes, el tamaño del repositorio cayó solo 10 kB. Por lo tanto, no se puede usar, por ejemplo, para hacer que el repositorio sea más pequeño y más rápido para transferir.
Jan Potužník
343

Una forma más fácil que funciona en cualquier sistema operativo es hacerlo

git rm -r --cached .
git add .
git commit -m "Removing all files in .gitignore"

Básicamente, leyó todos los archivos, excepto los que están en .gitignore

gtatr
fuente
1
¿Cómo afecta esto a otros usuarios en el repositorio que ejecutan un pull - mientras lo leo, la carpeta que ya no queremos rastrear se elimina? ¿Cómo podemos evitar esto? Solo queremos destrabarlo
Snh_nl
¡Esto marcará todos los archivos como modificados con un mensaje de confirmación falso!
Haidar Zeineddine
3
¿Qué quieres decir con mensaje de confirmación falso? Es un mensaje de compromiso real: P Puede cambiar el mensaje, por supuesto, dependiendo de sus necesidades ...
gtatr
1
Solo para completar, necesita el comando git push al final.
Mariusz
1
No hagas esto, eliminará el historial de todos los archivos
agrath
145

Como los archivos en .gitignore no están siendo rastreados, puede usar el comando git clean para eliminar de forma recursiva los archivos que no están bajo control de versiones.

Úselo git clean -xdnpara realizar una ejecución en seco y ver qué se eliminará.
Luego use git clean -xdfpara ejecutarlo.

Básicamente, git clean -ho man git-clean(en Unix) te dará ayuda.

Tenga en cuenta que este comando también eliminará los archivos nuevos que no están en el área de ensayo.

Espero eso ayude.

weiz
fuente
66
Esta debería ser la respuesta aceptada. Realmente funciona (la respuesta aceptada no funcionó para mí, en macOS), y es mucho más limpia.
Roger Oba
25
Esta respuesta no es aplicable: el OP dice que los archivos .gitignore están siendo rastreados.
Ken Williams
20
¡TENER CUIDADO! Esto elimina permanentemente todos los archivos no rastreados, en lugar de simplemente eliminarlos de la rama
Emmanuel
1
el git clean -xdnes un ensayo que no se borrará. el próximo lo hará.
JohnZaj
17
-1: Esta es una respuesta muy engañosa: el póster original quería eliminar del repositorio, no eliminar los archivos por completo. Estaba tan cerca de eliminar una carga de archivos dinámicos requeridos por mi IDE pero no requeridos para estar en el repositorio.
Auspicio
4

Hice una solución muy directa al manipular la salida de la declaración .gitignore con sed:

cat .gitignore | sed '/^#.*/ d' | sed '/^\s*$/ d' | sed 's/^/git rm -r /' | bash

Explicación:

  1. imprima el archivo .gitignore
  2. eliminar todos los comentarios de la impresión
  3. eliminar todas las líneas vacías
  4. agregue 'git rm -r' al comienzo de la línea
  5. ejecutar cada línea
Scott Crossen
fuente
10
sedes sencillo?
IgorGanapolsky
0

En Linux puedes usar este comando:

Por ejemplo, quiero eliminar "* .py ~", por lo que mi comando debería ser ==>

find . -name "*.py~" -exec rm -f {} \;

Saloua SAHNOUNE
fuente
-3

El git ignorará los archivos que coinciden con el patrón .gitignore después de agregarlo a .gitignore.

Pero los archivos que ya existían en el repositorio seguirán en.

use git rm files_ignored; git commit -m 'rm no use files'para eliminar archivos ignorados.

pensz
fuente
44
Hay muchos, ¿hay alguna forma de eliminarlos sin tener que especificar sus nombres?
Intrepidd