git clean -Xparece semelhante, mas não se aplica a essa situação (quando os arquivos ainda estão sendo rastreados pelo Git). Estou escrevendo isso para quem procura uma solução para não seguir o caminho errado.
imz - Ivan Zakharyaschev 27/02
35
A única resposta real para isso está abaixo, veja git update-index --assume-unchanged. Esta solução 1) mantém o arquivo no servidor (índice), 2) permite modificá-lo livremente localmente.
Uma pergunta importante é: o arquivo deve permanecer no repositório ou não? Por exemplo, se alguém novo clona o repositório, deve obter o arquivo ou não? Se SIM , então git update-index --assume-unchanged <file>é correto eo arquivo permanecerá no repositório e as alterações não serão adicionados com git add. Se NÃO (por exemplo, havia algum arquivo de cache, arquivo gerado etc.), ele git rm --cached <file>será removido do repositório.
Martin
9
@Martin @Qwerty Everyon deve parar para informar sobre --assume-unchangedqual é o desempenho para evitar que o git verifique o status de grandes arquivos rastreados, mas prefere o --skip-worktreeque é para arquivos rastreados modificados que o usuário não deseja mais confirmar. Veja stackoverflow.com/questions/13630849/…
Philippe
Respostas:
5705
.gitignoreimpedirá que add -farquivos não rastreados sejam adicionados (sem um ) ao conjunto de arquivos rastreados pelo git; no entanto, o git continuará rastreando todos os arquivos que já estão sendo rastreados.
Para parar de rastrear um arquivo, você precisa removê-lo do índice. Isso pode ser alcançado com este comando.
git rm --cached <file>
Se você deseja remover uma pasta inteira, é necessário remover todos os arquivos nela de forma recursiva.
git rm -r --cached <folder>
A remoção do arquivo da revisão principal ocorrerá no próximo commit.
AVISO: Embora isso não remova o arquivo físico do seu local, os arquivos de outras máquinas de desenvolvedores serão removidos na próxima git pull.
o processo que workd para mim foi 1. confirmar as alterações pendentes primeiro 2. git rm --cached <file> e comprometer novamente 3. adicionar o arquivo de .gitignore, cheque com git status e se comprometer novamente
mataal
117
Adicionando muito importante. Se o arquivo ignorado for modificado (mas, apesar disso, não deve ser confirmado), após a modificação e execução, git add .ele será adicionado ao índice. E o próximo commit o comprometeria no repositório. Para evitar isso, execute logo após tudo o que mataal disse mais um comando:git update-index --assume-unchanged <path&filename>
Dao
32
O método de @AkiraYamamoto também funcionou bem para mim. No meu caso, suprimi a saída, pois meu repositório tinha milhares de arquivos:git rm -r -q --cached .
Aaron Blenkush 11/11
85
Isso excluirá o arquivo no git pullentanto.
Petr Peller
22
O git rm --cached <file> apenas remove o arquivo do repositório, o git update-index --assume-inalterado <file> não mostra o arquivo em alterações não estágios e não faz com que o pull puxe novas alterações. Mas eu quero GIT simplesmente ignorar CONTEÚDO DE PLEEEEEASE ARQUIVO
Igor Semin
2610
A série de comandos abaixo removerá todos os itens do índice Git (não do diretório de trabalho ou repositório local) e atualiza o índice Git, respeitando o git ignorado. PS. Index = Cache
Para destacar a diferença entre esta resposta e a resposta aceita: Usando esses comandos, você não precisa conhecer realmente os arquivos afetados. (Imagine um diretório temporário com muitos arquivos aleatórios que devem ser limpos do índice).
Ludwig
53
O mesmo que a resposta aceita. Os arquivos serão excluídos git pull.
Petr Peller
73
Seria bom ter isso como um comando git padrão. Algo como git rmignored.
Berik
12
@gudthing -r significa "recursivo"
Mark
14
Com isso, você pode acabar adicionando outros arquivos inúteis que não estão no momento .gitignore. O que pode ser difícil de descobrir se, dependendo de quão barulho você git statusestiver após esse comando. Um comando que remove apenas arquivos recém-ignorados seria melhor. É por isso que eu prefiro a resposta de thSoft
KurzedMetal
1122
O git update-index faz o trabalho para mim:
git update-index --assume-unchanged <file>
Nota: Esta solução é realmente independente em.gitignore pois o gitignore é apenas para arquivos não rastreados.
editar: desde que esta resposta foi publicada, uma nova opção foi criada e deve ser preferida. Você deve usar o --skip-worktreeque é para arquivos rastreados modificados que o usuário não deseja mais confirmar e manter o --assume-unchangeddesempenho para evitar que o git verifique o status de grandes arquivos rastreados. Consulte https://stackoverflow.com/a/13631525/717372 para obter mais detalhes ...
Esta é a resposta real. Incrível, na verdade, muito simples, não polui git statuse é realmente muito intuitivo. Obrigado.
Pablo Olmos de Aguilera C.
4
Eu optei pela rm [...] .solução boa o suficiente , pois pelo menos conseguia entender como funcionava. Eu não encontrei nenhuma excelente documentação sobre o que update-indexe --assume-unchangedfazer. Alguém pode adicionar como isso se compara ao outro, porque eu gostaria de remover todos os arquivos que teriam sido ignorados? (Ou um link para uma explicação clara?)
Brady Trainor
25
git update-index --assume-unchanged <path> …fará com que o git ignore as alterações no (s) caminho (s) especificado (s), independentemente de .gitignore. Se você puxar de um controle remoto e esse controle tiver alterações nesse caminho, o git falhará na mesclagem com um conflito e você precisará mesclar manualmente. git rm --cached <path> …fará com que o git pare de rastrear esse caminho. Se você não adicionar o caminho .gitignore, verá o caminho no futuro git status. A primeira opção possui menos ruído no histórico de confirmação do git e permite que as alterações no arquivo "ignorado" sejam distribuídas no futuro.
ManicDee
26
Estou bastante confuso sobre como essa não é a resposta aceita. A resposta aceita aqui claramente não está respondendo à pergunta real que está sendo feita. Esta resposta ignora as alterações no arquivo que está no repositório enquanto não o remove do repositório.
Dave Cooper
11
Esta resposta seria muito mais útil se explicasse exatamente o que o comando fornecido faz, por exemplo, como é diferente das outras soluções sugeridas.
Se você precisar removê-los também do diretório de trabalho, basta executar git ls-files --ignored --exclude-standard | xargs git rm . Eu acredito que esta resposta é a melhor! Porque é muito claro, do jeito Unix, e faz a coisa desejada de maneira direta, sem compor os efeitos colaterais de outros comandos mais complexos.
imz - Ivan Zakharyaschev
6
Ótima resposta; no entanto, o comando falhará se você tiver caminhos com espaços no meio, por exemplo: "My dir / my_ignored_file.txt"
Ele lista todos os seus arquivos ignorados, substitui cada linha de saída por uma linha entre aspas para manipular caminhos com espaços internos e passar tudo para git rm -r --cached para remover os caminhos / arquivos / diretórios do índice.
Ótima solução! Funcionou perfeitamente e se sente mais correta que a remoção de todos os arquivos, em seguida, adicioná-los de volta.
Jon Catmull
5
Eu também achei isso "mais limpo". Pode ser óbvio, mas apenas a execução da primeira parte git ls-files --ignored --exclude-standardpermite que você entenda / verifique primeiro quais arquivos o seu novo .gitignoreexcluir / remover antes de executar a final git rm.
JonBrave
Esteja ciente, falha nos nomes de arquivos com certos caracteres "desagradáveis", por exemplo \n. Eu publiquei minha solução para atender a isso.
JonBrave
3
Outra ressalva: ao puxar, isso fará com que o arquivo seja excluído nos diretórios de trabalho de outras pessoas, certo?
precisa saber é
tentei, mas não funcionou para mim: sed: 1: "s/.*/": unterminated substitute in regular expressionem um comando filter-branch em um repositório com espaços. (Parecia funcionar fora do ramo do filtro). Eu usei da respostagit ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached de @ JonBrave .
Goofology 12/08/19
71
mova-o para fora, confirme e depois mova-o novamente. Isso funcionou para mim no passado. Provavelmente, existe uma maneira 'mais cuidadosa' de conseguir isso.
Isso funcionou muito bem se você deseja ignorar vários arquivos que não foram ignorados anteriormente. Embora, como você disse, provavelmente haja uma maneira melhor para isso.
Oskar Persson 28/05
Foi exatamente o que eu fiz. Simplesmente mova os arquivos para uma pasta fora do git e, em seguida, "git add.", "Git commit". (Isso removeu os arquivos), adicione o gitignore, fazendo referência aos arquivos / pastas, confirme novamente para adicionar o arquivo gitignore ao git, copie / mova de volta para as pastas e elas devem ser ignoradas. Nota: parece que os arquivos foram excluídos do GIT, portanto provavelmente os removeriam de outros checkouts / puxões, como mencionado nas soluções acima, mas como você está fazendo cópias deles inicialmente, isso não é um problema para o IMHO. basta deixar o resto do conhecimento da equipe ...
Del
Essa é a maneira mais fácil de se livrar de pastas comprometidas incorretamente.
precisa saber é o seguinte
2
Parece ser o único caminho que eu posso ver. É um bug enorme (não 'recurso') no git que, assim que você adiciona um arquivo / pasta ao .gitignore, ele não apenas ignora esse arquivo a partir desse ponto - para sempre - em qualquer lugar.
JosephK
Isso funcionou depois que eu tive-los adicionado, e em seguida, após o fato adicionou-los para .gitignore
hanzolo
66
Se você não puder git rmum arquivo rastreado porque outras pessoas precisam dele (aviso, mesmo que vocêgit rm --cached , quando outra pessoa receber essa alteração, os arquivos serão excluídos no sistema de arquivos). Isso geralmente é feito devido a substituições de arquivos de configuração, credenciais de autenticação etc. Por favor, consulte https://gist.github.com/1423106 para saber como as pessoas resolveram o problema.
Para resumir:
Faça com que seu aplicativo procure um arquivo ignorado config-overide.ini e use-o sobre o arquivo confirmado config.ini (ou, alternativamente, procure ~ / .config / myapp.ini ou $ MYCONFIGFILE)
Confirme o arquivo config-sample.ini e ignore o arquivo config.ini, tenha um script ou semelhante copie o arquivo conforme necessário, se necessário.
Tente usar a magia clean / smudge do gitattributes para aplicar e remover as alterações, por exemplo, borrar o arquivo de configuração como um checkout de uma ramificação alternativa e limpar o arquivo de configuração como um checkout do HEAD. Isso é complicado, eu não recomendo para o usuário iniciante.
Mantenha o arquivo de configuração em uma ramificação de implantação dedicada a ele que nunca é mesclada ao mestre. Quando você deseja implantar / compilar / testar, mescla esse ramo e obtém esse arquivo. Essa é essencialmente a abordagem smudge / clean, exceto o uso de políticas de mesclagem humana e módulos extra-git.
Anti-recommentação: Não use a função assumir inalterada, ela só terminará em lágrimas (porque mentir para si mesmo fará com que coisas ruins aconteçam, como a alteração perdida para sempre).
O git não removeria o arquivo se ele estivesse sujo no momento da exclusão. E se não estiver sujo, recuperar o arquivo seria tão fácil quanto git checkout <oldref> -- <filename>- mas seria verificado e ignorado.
amenthes
Com relação à sua última observação (sobre --assume-unchanged): ou isso é culto à carga e deve ser descartado, ou você pode explicar o porquê (do qual estou convencido) e se torna útil.
Digamos que você já tenha adicionado / confirmado alguns arquivos ao seu repositório git e depois os adicione ao seu .gitignore; esses arquivos ainda estarão presentes no seu índice de repositório. Este artigo vamos ver como se livrar deles.
Etapa 1: confirmar todas as suas alterações
Antes de continuar, verifique se todas as alterações foram confirmadas, incluindo o arquivo .gitignore.
Ele não excluirá os arquivos do repositório remoto? E se eu quiser manter os arquivos no repositório local e no repositório remoto, mas fazer o git "esquecê-los"?
Avishay28
AFAIK, isso não excluirá arquivos do histórico porque não estamos usando nenhum comando de alteração de histórico (corrija-me se estiver errado). Isso apenas adiciona um novo commit ao excluir arquivos ignorados no gitignore do git. Esses arquivos estarão lá no os comprometimentos históricos
Dheeraj Bhaskar 19/03/19
49
Eu consegui isso usando o filtro-ramo git . O comando exato que usei foi retirado da página de manual:
AVISO : isso excluirá o arquivo de todo o seu histórico
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
Este comando recriará todo o histórico de consolidação, executando git rmantes de cada consolidação e, portanto, eliminará o arquivo especificado. Não se esqueça de fazer backup antes de executar o comando, pois ele será perdido.
Isso mudará todos os IDs de confirmação, quebrando, assim, mesclagens de ramificações fora da sua cópia do repositório.
bdonlan
19
AVISO: isso excluirá o arquivo de todo o seu histórico. Era isso que eu estava procurando, para remover um arquivo completamente desnecessário e de grandes dimensões (saída que nunca deveria ter sido confirmada) que foi confirmada há muito tempo no histórico de versões.
Zebediah49 13/03/2013
48
O que não funcionou para mim
(No Linux), eu queria usar as postagens aqui sugerindo a ls-files --ignored --exclude-standard | xargs git rm -r --cachedabordagem. No entanto, (alguns dos) arquivos a serem removidos tinham uma nova linha / LF / incorporada \nem seus nomes. Nenhuma das soluções:
Isso usa o -zargumento para ls-files e o -0argumento para xargs para atender com segurança / corretamente caracteres "desagradáveis" nos nomes de arquivos.
Na página de manual git-ls-files (1) , afirma:
Quando a opção -z não é usada, os caracteres TAB, LF e barra invertida nos nomes dos caminhos são representados como \ t, \ n e \\, respectivamente.
então acho que minha solução é necessária se os nomes de arquivos tiverem algum desses caracteres.
Para mim, esta é a melhor solução. Tem um desempenho muito melhor que um git add .. Ele também contém as melhores melhorias de alguns comentários acima.
Nils-o-mat
Você pode adicionar o thSoft's git commit -am "Remove ignored files"posteriormente à sua resposta? Suas respostas combinadas me fez passar por coisas: j
Kando
Eu não entendo o propósito de git commit -a. Para mim git rm --cachedafetam exatamente o índice assim não há necessidade de preparar os arquivos depois ...
Jean Paul
23
Atualize seu .gitignorearquivo - por exemplo, adicione uma pasta para a qual não deseja rastrear .gitignore.
git rm -r --cached .- Remova todos os arquivos rastreados, incluindo os desejados e os indesejados. Seu código estará seguro enquanto você salvar localmente.
git add .- Todos os arquivos serão adicionados novamente, exceto os arquivos .gitignore.
Gorjeta de chapéu para @AkiraYamamoto por nos indicar a direção certa.
Que tal o voto negativo devido ao fato de que ele realmente não funcionará, pois você precisa de -r para executar rm de forma recursiva de qualquer maneira :) (Alguém não copiou corretamente) #
438 Aran
1
Aviso: Esta técnica não faz com que o git ignore o arquivo; em vez disso, faz com que o git exclua o arquivo. Isso significa que, se você usar esta solução, sempre que alguém fizer um git pull, o arquivo será excluído. Portanto, não é realmente ignorado. Veja a solução sugerindo git update-index --assume-inaltered para obter uma solução para a pergunta original.
Esse problema está ausente, por exemplo, ao usar o CVS. O CVS armazena informações como uma lista de alterações baseadas em arquivos. Informações para o CVS são um conjunto de arquivos e as alterações feitas em cada arquivo ao longo do tempo.
Mas no Git, toda vez que você confirma ou salva o estado do seu projeto, basicamente tira uma foto do que todos os seus arquivos aparência de naquele momento e armazena uma referência a esse instantâneo. Portanto, se você adicionou o arquivo uma vez, ele sempre estará presente nesse instantâneo.
Baseando-me, faça o seguinte, se o arquivo já estiver rastreado:
git update-index --skip-worktree <file>
A partir deste momento, todas as alterações locais neste arquivo serão ignoradas e não serão remotas. Se o arquivo for alterado no controle remoto, ocorrerá conflito quando git pull. Stash não vai funcionar. Para resolvê-lo, copie o conteúdo do arquivo para o local seguro e siga estas etapas:
O conteúdo do arquivo será substituído pelo conteúdo remoto. Cole suas alterações de um local seguro para arquivar e execute novamente:
git update-index --skip-worktree <file>
Se todos que trabalham com o projeto tiverem git update-index --skip-worktree <file>problemas, os problemas pulldevem estar ausentes. Esta solução é adequada para arquivos de configurações, quando cada desenvolvedor tem sua própria configuração de projeto.
Não é muito conveniente fazer isso sempre, quando o arquivo foi alterado no controle remoto, mas pode protegê-lo contra a substituição por conteúdo remoto.
Siga as etapas a seguir em série, você ficará bem.
1. remova os arquivos adicionados por engano do diretório / armazenamento . Você pode usar o comando "rm -r" (para linux) ou excluí-los navegando nos diretórios. Ou mova-os para outro local no seu PC. [Talvez você precise fechar o IDE se estiver executando para mover / remover ]
2. adicione os arquivos / diretórios ao gitignorearquivo agora e salve-o.
3. agora remova- os do cache do git usando estes comandos (se houver mais de um diretório, remova-os um por um emitindo repetidamente este comando)
git rm -r --cached path-to-those-files
4. agora faça um commit e push , use estes comandos. Isso removerá esses arquivos do git remote e fará com que o git pare de rastrear esses arquivos.
A resposta de Matt Fear foi o IMHO mais eficaz. A seguir, é apenas um script do PowerShell para quem está no Windows para remover apenas arquivos de seu repositório git que corresponda à sua lista de exclusão.
Em que situação essa lista de arquivos não será igual ao recursivo --cached?
John Zabroski
8
Mova ou copie o arquivo para um local seguro, para não perdê-lo. Em seguida, git rm o arquivo e confirme. O arquivo ainda será exibido se você reverter para uma dessas confirmações anteriores ou para outra ramificação em que não foi removida. No entanto, em todas as confirmações futuras, você não verá o arquivo novamente. Se o arquivo estiver no git ignore, você poderá movê-lo novamente para a pasta e o git não o verá.
O BFG foi projetado especificamente para remover dados indesejados, como arquivos grandes ou senhas, dos repositórios do Git, por isso possui um sinalizador simples que remove todos os grandes arquivos históricos (que não estão no seu commit atual): '--strip-blobs- maior que'
$ java -jar bfg.jar --strip-blobs-bigger-than 100M
Se você deseja especificar arquivos por nome, também pode fazer isso:
$ java -jar bfg.jar --delete-files *.mp4
O BFG é 10-1000x mais rápido que o git filter-branch e geralmente muito mais fácil de usar - consulte as instruções e exemplos de uso completos para obter mais detalhes.
Se você não quiser usar a CLI e estiver trabalhando no Windows, uma solução muito simples é usar o TortoiseGit , que possui a ação "Excluir (manter local)" no menu que funciona bem.
Gostei da resposta de JonBrave, mas tenho diretórios de trabalho confusos o suficiente que comprometem -a me assusta um pouco, então aqui está o que eu fiz:
Isso não é mais um problema no último git (v2.17.1 no momento da redação).
O .gitignorefinalmente ignora os arquivos rastreados, mas excluídos. Você pode testar isso executando o seguinte script. A git statusdeclaração final deve relatar "nada a confirmar".
# Create empty repo
mkdir gitignore-test
cd gitignore-test
git init
# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial
# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore
# Remove the file and commit
git rm file
git commit -m "removed file"
# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status
Estou feliz que o git agora faz isso. No entanto, o OP estava perguntando sobre o rastreamento de modificações nos arquivos presentes no .gitignore, os arquivos não excluídos ainda mostrando um status.
Lembre-se de que alguns desses arquivos armazenam algumas configurações e preferências locais do usuário para projetos (como os arquivos que você abriu). Portanto, toda vez que você navega ou faz algumas alterações em seu IDE, esse arquivo é alterado e, portanto, faz check-out e mostra como existem alterações não confirmadas.
A resposta aceita não "faz o Git " esquecer " um arquivo ..." (historicamente). Faz apenas o git ignorar o arquivo no presente / futuro.
Este método faz com que o git esqueça completamente os arquivos ignorados ( passado / presente / futuro), mas não exclui nada do diretório ativo (mesmo quando retirado novamente do controle remoto).
Este método requer o uso de /.git/info/exclude(preferencial) OU um pré-existente.gitignore em todas as confirmações que possuem arquivos a serem ignorados / esquecidos. 1
Todos os métodos de impor o git ignoram o comportamento depois que o fato reescreve o histórico e, portanto, têm ramificações significativas para quaisquer repositórios públicos / compartilhados / colaborativos que possam ser extraídos após esse processo. 2
Conselho geral: comece com um repositório limpo - tudo confirmado, nada pendente no diretório ou índice ativo e faça um backup !
#commit up-to-date .gitignore (if not already existing)#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"#apply standard git ignore behavior only to current index, not working directory (--cached)#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached
#Commit to prevent working directory data loss!#this commit will be automatically deleted by the --prune-empty flag in the following command#this command must be run on each branch
git commit -m "ignored index"#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above#This step will also delete any "empty" commits. If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command
git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch'--prune-empty --tag-name-filter cat ----all
#List all still-existing files that are now ignored properly#if this command returns nothing, it's time to restore from backup and start over#this command must be run on each branch
git ls-files --other --ignored --exclude-standard
Por fim, siga o restante deste guia do GitHub (começando na etapa 6), que inclui avisos / informações importantes sobre os comandos abaixo .
Outros desenvolvedores que obtêm do repositório remoto modificado agora devem fazer um backup e, em seguida:
#fetch modified remote
git fetch --all
#"Pull" changes WITHOUT deleting newly-ignored files from working directory#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed
git reset FETCH_HEAD
Notas de rodapé
1 Como /.git/info/excludepode ser aplicado a todas as confirmações históricas usando as instruções acima, talvez os detalhes sobre a inserção de um .gitignorearquivo nas confirmações históricas necessárias estejam além do escopo desta resposta. Eu queria que um apropriado .gitignoreestivesse no commit raiz, como se fosse a primeira coisa que fiz. Outros podem não se importar, pois /.git/info/excludepodem realizar a mesma coisa, independentemente de onde .gitignoreexista no histórico de confirmação, e reescrever claramente o histórico é um assunto muito delicado, mesmo quando está ciente das ramificações .
FWIW, métodos potenciais podem incluir git rebaseou um git filter-branchque copia um externo.gitignore para cada confirmação, como as respostas a esta pergunta
2 A imposição do comportamento do git ignore após a confirmação dos resultados de um git rm --cachedcomando independente pode resultar na exclusão de arquivos recém-ignorados em futuras tentativas do controle remoto forçado. O --prune-emptysinalizador no git filter-branchcomando a seguir evita esse problema removendo automaticamente a confirmação somente do índice "excluir todos os arquivos ignorados" anterior. Reescrever o histórico do git também altera os hashes de confirmação, o que causará estragos em futuras solicitações de repositórios públicos / compartilhados / colaborativos. Por favor, entenda as ramificações completamente antes de fazer isso em um repositório desse tipo. Este guia do GitHub especifica o seguinte:
Diga a seus colaboradores para refazer , e não mesclar, quaisquer ramificações que eles criaram do histórico de repositório antigo (contaminado). Um commit de mesclagem pode reintroduzir parte ou toda a história corrompida que você acabou de dar ao trabalho de eliminar.
Soluções alternativas que não afetam o repositório remoto são git update-index --assume-unchanged </path/file>ou git update-index --skip-worktree <file>, exemplos dos quais podem ser encontrados aqui .
No meu caso aqui, eu tinha vários arquivos .lock em vários diretórios que precisava remover. Eu executei o seguinte e funcionou sem ter que entrar em cada diretório para removê-los:
git rm -r --cached **/*.lock
Fazer isso foi para cada pasta na 'raiz' de onde eu estava e excluiu todos os arquivos que correspondiam ao padrão.
git clean -X
parece semelhante, mas não se aplica a essa situação (quando os arquivos ainda estão sendo rastreados pelo Git). Estou escrevendo isso para quem procura uma solução para não seguir o caminho errado.git update-index --assume-unchanged
. Esta solução 1) mantém o arquivo no servidor (índice), 2) permite modificá-lo livremente localmente.--skip-worktree
, consulte: stackoverflow.com/questions/13630849/…git update-index --assume-unchanged <file>
é correto eo arquivo permanecerá no repositório e as alterações não serão adicionados comgit add
. Se NÃO (por exemplo, havia algum arquivo de cache, arquivo gerado etc.), elegit rm --cached <file>
será removido do repositório.--assume-unchanged
qual é o desempenho para evitar que o git verifique o status de grandes arquivos rastreados, mas prefere o--skip-worktree
que é para arquivos rastreados modificados que o usuário não deseja mais confirmar. Veja stackoverflow.com/questions/13630849/…Respostas:
.gitignore
impedirá queadd -f
arquivos não rastreados sejam adicionados (sem um ) ao conjunto de arquivos rastreados pelo git; no entanto, o git continuará rastreando todos os arquivos que já estão sendo rastreados.Para parar de rastrear um arquivo, você precisa removê-lo do índice. Isso pode ser alcançado com este comando.
Se você deseja remover uma pasta inteira, é necessário remover todos os arquivos nela de forma recursiva.
A remoção do arquivo da revisão principal ocorrerá no próximo commit.
AVISO: Embora isso não remova o arquivo físico do seu local, os arquivos de outras máquinas de desenvolvedores serão removidos na próxima
git pull
.fonte
git add .
ele será adicionado ao índice. E o próximo commit o comprometeria no repositório. Para evitar isso, execute logo após tudo o que mataal disse mais um comando:git update-index --assume-unchanged <path&filename>
git rm -r -q --cached .
git pull
entanto.A série de comandos abaixo removerá todos os itens do índice Git (não do diretório de trabalho ou repositório local) e atualiza o índice Git, respeitando o git ignorado. PS. Index = Cache
Primeiro:
Então:
Ou uma linha:
fonte
git pull
.git rmignored
..gitignore
. O que pode ser difícil de descobrir se, dependendo de quão barulho vocêgit status
estiver após esse comando. Um comando que remove apenas arquivos recém-ignorados seria melhor. É por isso que eu prefiro a resposta de thSoftO git update-index faz o trabalho para mim:
Nota: Esta solução é realmente independente em
.gitignore
pois o gitignore é apenas para arquivos não rastreados.editar: desde que esta resposta foi publicada, uma nova opção foi criada e deve ser preferida. Você deve usar o
--skip-worktree
que é para arquivos rastreados modificados que o usuário não deseja mais confirmar e manter o--assume-unchanged
desempenho para evitar que o git verifique o status de grandes arquivos rastreados. Consulte https://stackoverflow.com/a/13631525/717372 para obter mais detalhes ...fonte
git status
e é realmente muito intuitivo. Obrigado.rm [...] .
solução boa o suficiente , pois pelo menos conseguia entender como funcionava. Eu não encontrei nenhuma excelente documentação sobre o queupdate-index
e--assume-unchanged
fazer. Alguém pode adicionar como isso se compara ao outro, porque eu gostaria de remover todos os arquivos que teriam sido ignorados? (Ou um link para uma explicação clara?)git update-index --assume-unchanged <path> …
fará com que o git ignore as alterações no (s) caminho (s) especificado (s), independentemente de.gitignore
. Se você puxar de um controle remoto e esse controle tiver alterações nesse caminho, o git falhará na mesclagem com um conflito e você precisará mesclar manualmente.git rm --cached <path> …
fará com que o git pare de rastrear esse caminho. Se você não adicionar o caminho.gitignore
, verá o caminho no futurogit status
. A primeira opção possui menos ruído no histórico de confirmação do git e permite que as alterações no arquivo "ignorado" sejam distribuídas no futuro.Isso pega a lista dos arquivos ignorados e os remove do índice e confirma as alterações.
fonte
git ls-files --ignored --exclude-standard | xargs git rm
. Eu acredito que esta resposta é a melhor! Porque é muito claro, do jeito Unix, e faz a coisa desejada de maneira direta, sem compor os efeitos colaterais de outros comandos mais complexos.git rm
reclamará sels-files
não corresponder a nada. Usexargs -r git rm ...
para dizer paraxargs
não executargit rm
se nenhum arquivo corresponder.git ls-files --ignored --exclude-standard -z|xargs -0 git rm --cached
Eu sempre uso esse comando para remover os arquivos não rastreados. Saída limpa de uma linha, estilo Unix:
Ele lista todos os seus arquivos ignorados, substitui cada linha de saída por uma linha entre aspas para manipular caminhos com espaços internos e passar tudo para
git rm -r --cached
para remover os caminhos / arquivos / diretórios do índice.fonte
git ls-files --ignored --exclude-standard
permite que você entenda / verifique primeiro quais arquivos o seu novo.gitignore
excluir / remover antes de executar a finalgit rm
.\n
. Eu publiquei minha solução para atender a isso.sed: 1: "s/.*/": unterminated substitute in regular expression
em um comando filter-branch em um repositório com espaços. (Parecia funcionar fora do ramo do filtro). Eu usei da respostagit ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
de @ JonBrave .mova-o para fora, confirme e depois mova-o novamente. Isso funcionou para mim no passado. Provavelmente, existe uma maneira 'mais cuidadosa' de conseguir isso.
fonte
Se você não puder
git rm
um arquivo rastreado porque outras pessoas precisam dele (aviso, mesmo que vocêgit rm --cached
, quando outra pessoa receber essa alteração, os arquivos serão excluídos no sistema de arquivos). Isso geralmente é feito devido a substituições de arquivos de configuração, credenciais de autenticação etc. Por favor, consulte https://gist.github.com/1423106 para saber como as pessoas resolveram o problema.Para resumir:
fonte
git checkout <oldref> -- <filename>
- mas seria verificado e ignorado.--assume-unchanged
): ou isso é culto à carga e deve ser descartado, ou você pode explicar o porquê (do qual estou convencido) e se torna útil.Use isso quando:
1. Você deseja rastrear muitos arquivos ou
2. Você atualizou seu arquivo gitignore
Digamos que você já tenha adicionado / confirmado alguns arquivos ao seu repositório git e depois os adicione ao seu .gitignore; esses arquivos ainda estarão presentes no seu índice de repositório. Este artigo vamos ver como se livrar deles.
Etapa 1: confirmar todas as suas alterações
Antes de continuar, verifique se todas as alterações foram confirmadas, incluindo o arquivo .gitignore.
Etapa 2: Remova tudo do repositório
Para limpar seu repo, use:
O
rm
comando pode ser implacável. Se você quiser tentar o que faz antes, adicione o-n
ou--dry-run
sinalizador para testar as coisas.Etapa 3: adicione novamente tudo
Etapa 4: confirmar
Seu repositório está limpo :)
Envie as alterações para o controle remoto para ver as alterações efetivas também.
fonte
Eu consegui isso usando o filtro-ramo git . O comando exato que usei foi retirado da página de manual:
AVISO : isso excluirá o arquivo de todo o seu histórico
Este comando recriará todo o histórico de consolidação, executando
git rm
antes de cada consolidação e, portanto, eliminará o arquivo especificado. Não se esqueça de fazer backup antes de executar o comando, pois ele será perdido.fonte
O que não funcionou para mim
(No Linux), eu queria usar as postagens aqui sugerindo a
ls-files --ignored --exclude-standard | xargs git rm -r --cached
abordagem. No entanto, (alguns dos) arquivos a serem removidos tinham uma nova linha / LF / incorporada\n
em seus nomes. Nenhuma das soluções:lidar com esta situação (obter erros sobre arquivos não encontrados).
Então eu ofereço
Isso usa o
-z
argumento para ls-files e o-0
argumento para xargs para atender com segurança / corretamente caracteres "desagradáveis" nos nomes de arquivos.Na página de manual git-ls-files (1) , afirma:
então acho que minha solução é necessária se os nomes de arquivos tiverem algum desses caracteres.
fonte
git add .
. Ele também contém as melhores melhorias de alguns comentários acima.git commit -am "Remove ignored files"
posteriormente à sua resposta? Suas respostas combinadas me fez passar por coisas: jgit commit -a
. Para mimgit rm --cached
afetam exatamente o índice assim não há necessidade de preparar os arquivos depois ...Atualize seu
.gitignore
arquivo - por exemplo, adicione uma pasta para a qual não deseja rastrear.gitignore
.git rm -r --cached .
- Remova todos os arquivos rastreados, incluindo os desejados e os indesejados. Seu código estará seguro enquanto você salvar localmente.git add .
- Todos os arquivos serão adicionados novamente, exceto os arquivos.gitignore
.Gorjeta de chapéu para @AkiraYamamoto por nos indicar a direção certa.
fonte
Eu acho que talvez o git não possa esquecer totalmente o arquivo por causa de sua concepção ( seção "Instantâneos, não diferenças" ).
Esse problema está ausente, por exemplo, ao usar o CVS. O CVS armazena informações como uma lista de alterações baseadas em arquivos. Informações para o CVS são um conjunto de arquivos e as alterações feitas em cada arquivo ao longo do tempo.
Mas no Git, toda vez que você confirma ou salva o estado do seu projeto, basicamente tira uma foto do que todos os seus arquivos aparência de naquele momento e armazena uma referência a esse instantâneo. Portanto, se você adicionou o arquivo uma vez, ele sempre estará presente nesse instantâneo.
Estes 2 artigos foram úteis para mim:
git assume-inalterado vs skip-worktree e Como ignorar alterações nos arquivos rastreados com o Git
Baseando-me, faça o seguinte, se o arquivo já estiver rastreado:
A partir deste momento, todas as alterações locais neste arquivo serão ignoradas e não serão remotas. Se o arquivo for alterado no controle remoto, ocorrerá conflito quando
git pull
. Stash não vai funcionar. Para resolvê-lo, copie o conteúdo do arquivo para o local seguro e siga estas etapas:O conteúdo do arquivo será substituído pelo conteúdo remoto. Cole suas alterações de um local seguro para arquivar e execute novamente:
Se todos que trabalham com o projeto tiverem
git update-index --skip-worktree <file>
problemas, os problemaspull
devem estar ausentes. Esta solução é adequada para arquivos de configurações, quando cada desenvolvedor tem sua própria configuração de projeto.Não é muito conveniente fazer isso sempre, quando o arquivo foi alterado no controle remoto, mas pode protegê-lo contra a substituição por conteúdo remoto.
fonte
Siga as etapas a seguir em série, você ficará bem.
1. remova os arquivos adicionados por engano do diretório / armazenamento . Você pode usar o comando "rm -r" (para linux) ou excluí-los navegando nos diretórios. Ou mova-os para outro local no seu PC. [Talvez você precise fechar o IDE se estiver executando para mover / remover ]
2. adicione os arquivos / diretórios ao
gitignore
arquivo agora e salve-o.3. agora remova- os do cache do git usando estes comandos (se houver mais de um diretório, remova-os um por um emitindo repetidamente este comando)
4. agora faça um commit e push , use estes comandos. Isso removerá esses arquivos do git remote e fará com que o git pare de rastrear esses arquivos.
fonte
A resposta copiar / colar é
git rm --cached -r .; git add .; git status
Este comando ignorará os arquivos que já foram confirmados em um repositório Git, mas agora os adicionamos
.gitignore
.fonte
A resposta de Matt Fear foi o IMHO mais eficaz. A seguir, é apenas um script do PowerShell para quem está no Windows para remover apenas arquivos de seu repositório git que corresponda à sua lista de exclusão.
fonte
Mova ou copie o arquivo para um local seguro, para não perdê-lo. Em seguida, git rm o arquivo e confirme. O arquivo ainda será exibido se você reverter para uma dessas confirmações anteriores ou para outra ramificação em que não foi removida. No entanto, em todas as confirmações futuras, você não verá o arquivo novamente. Se o arquivo estiver no git ignore, você poderá movê-lo novamente para a pasta e o git não o verá.
fonte
git rm --cached
irá remover o arquivo do índice sem excluí-lo do disco, por isso não há necessidade de mover / copiar-lo afastadoO uso do
git rm --cached
comando não responde à pergunta original:De fato, esta solução fará com que o arquivo seja excluído em todas as outras instâncias do repositório ao executar um
git pull
!A maneira correta de forçar o git a esquecer um arquivo é documentada pelo GitHub aqui .
Eu recomendo a leitura da documentação, mas basicamente:
apenas substitua
full/path/to/file
pelo caminho completo do arquivo. Verifique se você adicionou o arquivo ao seu.gitignore
.Você também precisará (temporariamente) permitir empurrões de avanço rápido para seu repositório , pois está alterando seu histórico do git.
fonte
O BFG foi projetado especificamente para remover dados indesejados, como arquivos grandes ou senhas, dos repositórios do Git, por isso possui um sinalizador simples que remove todos os grandes arquivos históricos (que não estão no seu commit atual): '--strip-blobs- maior que'
Se você deseja especificar arquivos por nome, também pode fazer isso:
O BFG é 10-1000x mais rápido que o git filter-branch e geralmente muito mais fácil de usar - consulte as instruções e exemplos de uso completos para obter mais detalhes.
Fonte: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html
fonte
Se você não quiser usar a CLI e estiver trabalhando no Windows, uma solução muito simples é usar o TortoiseGit , que possui a ação "Excluir (manter local)" no menu que funciona bem.
fonte
Gostei da resposta de JonBrave, mas tenho diretórios de trabalho confusos o suficiente que comprometem -a me assusta um pouco, então aqui está o que eu fiz:
git config - global alias.exclude-ignorado '! git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached && git ls-files -z --ignored --exclude-standard | xargs -0 git stage && git stage .gitignore && git commit -m "novo gitignore e remova arquivos ignorados do índice" '
dividindo:
fonte
Isso não é mais um problema no último git (v2.17.1 no momento da redação).
O
.gitignore
finalmente ignora os arquivos rastreados, mas excluídos. Você pode testar isso executando o seguinte script. Agit status
declaração final deve relatar "nada a confirmar".fonte
No caso de já estar comprometido
DS_Store
:Ignore-os por:
Finalmente, faça um commit!
fonte
Especialmente para os arquivos baseados em IDE, eu uso este:
Por exemplo, o slnx.sqlite, acabei de me livrar completamente da seguinte maneira:
Lembre-se de que alguns desses arquivos armazenam algumas configurações e preferências locais do usuário para projetos (como os arquivos que você abriu). Portanto, toda vez que você navega ou faz algumas alterações em seu IDE, esse arquivo é alterado e, portanto, faz check-out e mostra como existem alterações não confirmadas.
fonte
Por fim, siga o restante deste guia do GitHub (começando na etapa 6), que inclui avisos / informações importantes sobre os comandos abaixo .
Outros desenvolvedores que obtêm do repositório remoto modificado agora devem fazer um backup e, em seguida:
Notas de rodapé
1 Como
/.git/info/exclude
pode ser aplicado a todas as confirmações históricas usando as instruções acima, talvez os detalhes sobre a inserção de um.gitignore
arquivo nas confirmações históricas necessárias estejam além do escopo desta resposta. Eu queria que um apropriado.gitignore
estivesse no commit raiz, como se fosse a primeira coisa que fiz. Outros podem não se importar, pois/.git/info/exclude
podem realizar a mesma coisa, independentemente de onde.gitignore
exista no histórico de confirmação, e reescrever claramente o histórico é um assunto muito delicado, mesmo quando está ciente das ramificações .FWIW, métodos potenciais podem incluir
git rebase
ou umgit filter-branch
que copia um externo.gitignore
para cada confirmação, como as respostas a esta pergunta2 A imposição do comportamento do git ignore após a confirmação dos resultados de um
git rm --cached
comando independente pode resultar na exclusão de arquivos recém-ignorados em futuras tentativas do controle remoto forçado. O--prune-empty
sinalizador nogit filter-branch
comando a seguir evita esse problema removendo automaticamente a confirmação somente do índice "excluir todos os arquivos ignorados" anterior. Reescrever o histórico do git também altera os hashes de confirmação, o que causará estragos em futuras solicitações de repositórios públicos / compartilhados / colaborativos. Por favor, entenda as ramificações completamente antes de fazer isso em um repositório desse tipo. Este guia do GitHub especifica o seguinte:Soluções alternativas que não afetam o repositório remoto são
git update-index --assume-unchanged </path/file>
ougit update-index --skip-worktree <file>
, exemplos dos quais podem ser encontrados aqui .fonte
Se alguém com dificuldade no Windows e você deseja ignorar a pasta inteira, 'cd' deseja a 'pasta' e faça 'Git Bash Here'.
fonte
No meu caso aqui, eu tinha vários arquivos .lock em vários diretórios que precisava remover. Eu executei o seguinte e funcionou sem ter que entrar em cada diretório para removê-los:
Fazer isso foi para cada pasta na 'raiz' de onde eu estava e excluiu todos os arquivos que correspondiam ao padrão.
Espero que isso ajude os outros!
fonte