Como remover arquivos listados no .gitignore, mas ainda no repositório?

327

Eu tenho alguns arquivos no meu repositório que devem ser ignorados, eu os adicionei ao .gitignore, mas é claro que eles não são removidos do meu repositório.

Portanto, minha pergunta é: existe um comando ou script mágico usando o branch-filter que pode reescrever meu histórico e remover todos esses arquivos facilmente? Ou simplesmente um comando que criará uma confirmação que os removerá?

Intrepidd
fonte
AVISO: Embora isso não remova o arquivo físico do seu local, ele removerá os arquivos de outras máquinas de desenvolvedores no próximo git pull. Como fazer o Git "esquecer" um arquivo que foi rastreado, mas que agora está no .gitignore?
precisa saber é o seguinte
@Stevoisiak, essa não é uma duplicata dessa pergunta, porque esta pergunta sobre TODOS os arquivos ignorados e também tem uma resposta melhor do que qualquer uma das perguntas semelhantes.
21719

Respostas:

438

Você pode removê-los do repositório manualmente:

git rm --cached file1 file2 dir/file3

Ou, se você tiver muitos arquivos:

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

Mas isso não parece funcionar no Git Bash no Windows. Produz uma mensagem de erro. O seguinte funciona melhor:

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

Em relação à reescrita de toda a história sem esses arquivos, duvido muito que exista uma maneira automática de fazer isso.
E todos sabemos que reescrever a história é ruim, não é? :)

Samy Dindane
fonte
2
Infelizmente, o Bash Git no comando do Windows não funciona com caminhos que contêm espaços
Nate Bundy
19
@ Cupcake thanks. git ls-files -i -z --exclude-from=.gitignore | xargs -0 git rm --cachedparece fazer o truque
Nate Bundy
3
Fiquei preso com o mesmo problema no Windows. Estou usando o PowerShell e, no meu caso, recebi o terceiro comando com a dica @ samy-dindane e o mudei para um foreach. Tornou-se istogit ls-files -i --exclude-from=.gitignore | %{git rm --cached $_}
digaomatias
1
"git ls-files -i --exclude-from = .gitignore" é muito útil, ele me diz quais arquivos são excluídos por .ignore.
Owen Cao
1
Fiquei feliz em encontrar esses comandos, mas ele realmente não remove os arquivos do repositório. Quando removi 2300 kB de imagens, o tamanho do repositório caiu apenas 10 kB. Portanto, não pode ser usado, por exemplo, para tornar o repositório menor e mais rápido para transferir.
Jan Potužník 22/02/19
343

Uma maneira mais fácil que funciona em qualquer sistema operacional é fazer

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

Você basicamente lê todos os arquivos, exceto os do .gitignore

gtatr
fonte
1
Como isso afeta outros usuários no repositório que executam um pull - enquanto eu leio, a pasta que não queremos mais rastrear é excluída ??? Como podemos evitar isso - nós só queremos untrack
snh_nl
Isso marcará todos os arquivos como alterados com uma mensagem de confirmação falsa!
Haidar Zeineddine 26/07/19
3
o que você quer dizer com mensagem de confirmação falsa? É uma verdadeira mensagem cometer: P Você pode mudar a mensagem é claro, dependendo de suas necessidades ...
gtatr
1
Por uma questão de integridade, você precisa do comando git push no final.
Mariusz Bialobrzeski 03/03
1
Não faça isso, ele removerá o histórico de todos os arquivos
agrath
145

Como os arquivos no .gitignore não estão sendo rastreados, você pode usar o comando git clean para remover recursivamente os arquivos que não estão sob controle de versão.

Use git clean -xdnpara executar uma corrida a seco e ver o que será removido.
Então use git clean -xdfpara executá-lo.

Basicamente, git clean -hou man git-clean(em unix) lhe dará ajuda.

Esteja ciente de que este comando também removerá novos arquivos que não estão na área de preparação.

Espero que ajude.

weiz
fonte
6
Essa deve ser a resposta aceita. Na verdade, funciona (a resposta aceita não funcionou para mim, no macOS), e é muito mais limpa.
Roger Oba
25
Esta resposta não é aplicável - o OP diz que os arquivos .gitignore estão sendo rastreados.
Ken Williams
20
Cuidado! Isso exclui permanentemente todos os arquivos untracked, ao invés de apenas a remoção do ramo
Emmanuel
1
a git clean -xdné uma execução a seco que não será excluída. o próximo será.
JohnZaj
17
-1: Esta é uma resposta altamente enganadora - o pôster original queria remover do repositório, não os arquivos completamente. Eu estava tão perto de excluir uma carga de arquivos dinâmicos exigidos pelo meu IDE, mas não de estar no repositório.
Auspice
4

Eu fiz uma solução muito simples, manipulando a saída da instrução .gitignore com sed:

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

Explicação:

  1. imprima o arquivo .gitignore
  2. remova todos os comentários da impressão
  3. excluir todas as linhas vazias
  4. adicione 'git rm -r' ao início da linha
  5. execute todas as linhas.
Scott Crossen
fonte
10
sedé simples?
IgorGanapolsky 13/09
0

No linux, você pode usar este comando:

por exemplo, eu quero excluir "* .py ~", então meu comando deve ser ==>

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

Saloua SAHNOUNE
fonte
-3

O git ignorará os arquivos correspondentes ao padrão .gitignore depois de adicioná-lo ao .gitignore.

Mas os arquivos já existentes no repositório ainda estarão no.

use git rm files_ignored; git commit -m 'rm no use files'para excluir arquivos ignorados.

pensz
fonte
4
Existem muitos deles, existe uma maneira de excluí-los sem precisar especificar seus nomes?
Intrepidd