Remova um arquivo de um repositório Git sem excluí-lo do sistema de arquivos local


3048

Meu commit inicial continha alguns arquivos de log. Eu adicionei *logao meu .gitignoree agora quero remover os arquivos de log do meu repositório.

git rm mylogfile.log

removerá um arquivo do repositório, mas também o removerá do sistema de arquivos local.

Como posso remover este arquivo do repositório sem excluir minha cópia local do arquivo?



14
Vale a pena notar que a resposta mais votada é perigosa para alguns. Se você estiver usando um repositório remoto do que quando envia o seu local, puxe para outro lugar os arquivos que você removeu do git, somente serão excluídos . Isso é mencionado em uma das respostas, mas não comentado.
— RichieHH

Respostas:


4354

No arquivo man :

Quando --cachedé fornecido, o conteúdo faseado deve corresponder à ponta da ramificação ou ao arquivo no disco, permitindo que o arquivo seja removido apenas do índice.

Então, para um único arquivo:

git rm --cached mylogfile.log

e para um único diretório:

git rm --cached -r mydirectory

151
Facilmente esquecido, porque não é tão auto-explicativo quanto svn rm --keep-local.
— Martin

114
Mas como preservo os arquivos em servidores remotos? Isso mantém o local, mas se eu pressionar e puxar de outro servidor, o arquivo será excluído. Eu também adicionei um .gitignore para o arquivo, mas ele ainda é removido
— Spankmaster79

6
Isso ainda remove os arquivos git pullse você estiver por trás do commit depois #git rm
— Petr Peller

9
Vale ressaltar que, depois de executar o comando na resposta, você precisa usar git commit -m "Commit message"e git push. Se você tiver outras alterações em etapas (verifique com git status), elas também serão confirmadas no momento.
— Sinjai 11/09/17

9
Como esta é a resposta mais aceita e não faz, o que é solicitado, vou dizer o que faço. Eu uso o comando git rm --cached mylogfile.loge excluo o arquivo do repositório. Para evitar a perda do arquivo no sistema produtivo, faço um backup do arquivo e puxo depois disso. O arquivo é excluído como mencionado anteriormente e precisa ser copiado novamente do seu backup. Isso é bastante doloroso, mas não encontrei uma solução melhor para esse problema.
— Marcel grolms

275

Para remover uma pasta inteira do repositório (como arquivos de novo compartilhador), faça o seguinte:

git rm -r --cached folderName

Eu havia comprometido alguns arquivos de novo compartilhamento e não queria que eles persistissem para outros usuários do projeto.


13
Apenas uma observação adicional para futuros visitantes: não use uma GUI para "sincronizar" a confirmação de volta ao repositório. Isso fará com que os arquivos retornem ao seu repositório local. Você precisa fazer um Git Push repo branchpara remover os arquivos do controle remoto.
— precisa

211

Você também pode remover arquivos do repositório com base no seu .gitignore sem excluí-los do sistema de arquivos local:

git rm --cached `git ls-files -i -X .gitignore`

Ou, alternativamente, no Windows Powershell:

git rm --cached $(git ls-files -i -X .gitignore)

7
Não funciona no Windows. git ls-files -i -X ​​.gitignore funciona, mas não sei como enviar os arquivos para 'git rm'. voce sabe como fazer isso?
— Erik Z

17
Funciona no Windows se você usar o Git Bash em vez do cmd-console
— Andreas Zita

17
Amo isso. Funcionou, exceto que eu tinha alguns arquivos que acabaram tendo espaços no nome do arquivo. Eu modifiquei solução aqui para isso: git ls-files -i -X .gitignore | xargs -I{} git rm --cached "{}". Por favor, considere modificar ou adicionar esta solução para a resposta aqui, porque é uma ótima ferramenta para ter ...
— mpettis

Eu não tentei, mas ele deve ser testado, ele removerá também arquivos como o .gitkeepque preserva uma pasta vazia no repositório. Por exemplo. .gitignorepasta uploadse o repositório é forçado a acompanhar .gitkeep. Ao remover tudo do repo sob uploadsele removerá também .gitkeep.
— Vladimir Vukanac 07/07/16

Esta sugestão funcionou perfeitamente no powershell: git rm --cached $ (git ls-files -i -X ​​.gitignore)
— geekandglitter

89

Conforme minha resposta aqui: /programming/6313126/how-to-remove-a-directory-in-my-github-repository

Para remover a pasta / diretório ou arquivo apenas do repositório git e não do local, tente 3 etapas simples.


Etapas para remover o diretório

git rm -r --cached File-or-FolderName
git commit -m "Removed folder from repository"
git push origin master

Etapas para ignorar essa pasta nas próximas confirmações

Para ignorar essa pasta das próximas confirmações, crie um arquivo na raiz chamado .gitignore e coloque o nome dessa pasta nela. Você pode colocar quantas quiser

O arquivo .gitignore ficará assim

/FolderName

remover diretório


@gaurav feliz que ajudou!
— eirenaios

69

Além disso, se você confirmou dados confidenciais (por exemplo, um arquivo contendo senhas), exclua-os completamente do histórico do repositório. Aqui está um guia explicando como fazer isso: http://help.github.com/remove-sensitive-data/


13
Esta resposta deve incluir os comandos necessários para concluir esta tarefa em vez de criar um link para outro site.
— Florian Lemaitre

1
Gostaria também de observar que achei mais fácil e rápido o uso da ferramenta de limpeza de repositórios git bfg .
— Lubed Up Slug

64

Uma solução mais genérica:

  1. Edite o .gitignorearquivo.

    ECHO mylogfile.log >> .gitignore

  2. Remova todos os itens do índice.

    git rm -r -f --cached .

  3. Recrie o índice.

    git add .

  4. Fazer nova confirmação

    git commit -m "Removed mylogfile.log"


2
Isso realmente excluirá o arquivo?
— Mr_and_Mrs_D

6
Do GitHub? NÃO. Se você já empurrou para o github, ele não o removerá do site. Mas ele atualizará seu repositório git local.
— MST3RpEE

5
O comentário que você excluiu foi mais eliminado na verdade :) O problema com a solução rm --cashedé que ela acabará excluindo o arquivo quando você o puxar - certo? E não é isso que as pessoas querem quando dizem "Remover um arquivo do repositório sem excluí-lo do sistema de arquivos local ". Agora, por que a solução acima aceita está além de mim - provavelmente o OP estava trabalhando sozinho e nunca foi puxado? Não sei. Eu entendo o problema do github "uma vez empurrado sempre lá" ofc
— Mr_and_Mrs_D

Eu não acho que exista uma solução 100%, a menos que você pergunte o próprio github. Por enquanto, atenha-se a isso. Copie o arquivo, adicione ao gitignore, faça o git rm -r real, confirme, pressione, restaure o arquivo. Você conseguiu encontrar outra solução?
— MST3RpEE

9
Meu problema não é o github - é que o arquivo será realmente excluído dos colegas de trabalho quando eles puxarem . Eu não quero que o arquivo a ser excluído. Isso me causou grandes problemas no passado. Então, eu queria saber se existe realmente uma solução que realmente não apaga o arquivo. Veja também o comentário na resposta aceita: stackoverflow.com/questions/1143796/…
— Mr_and_Mrs_D

24

O Git permite que você ignore esses arquivos, assumindo que eles não são alterados. Isso é feito executando o git update-index --assume-unchanged path/to/file.txtcomando Depois de marcar um arquivo como tal, o git ignorará completamente qualquer alteração nesse arquivo; eles não aparecerão ao executar o status git ou git diff, nem serão comprometidos.

(Em https://help.github.com/articles/ignoring-files )

Portanto, não a exclua, mas ignore as alterações para sempre. Eu acho que isso só funciona localmente, então os colegas de trabalho ainda podem ver alterações, a menos que executem o mesmo comando acima. (Ainda é necessário verificar isso.)

Nota: Isso não está respondendo diretamente à pergunta, mas é baseado nas perguntas de acompanhamento nos comentários das outras respostas.


2
Hum, eu faço isso, mas vejo que o arquivo pode ser substituído se alguém fizer alterações no repositório.
— AlxVallejo 15/09

17

Se você deseja apenas rastrear um arquivo e não excluir do repositório local e remoto, use este comando:

git update-index --assume-unchanged  file_name_with_path

2
Embora essa seja uma boa resposta, é importante observar que isso não "rastreia" um arquivo no sentido de que as pessoas geralmente usam essa palavra com o Git, onde um arquivo não rastreado é aquele que não está no histórico do repositório e nunca foi encontrado. . O que essa resposta faz é manter o arquivo no repositório, mas impedir que o Git note que as alterações foram feitas nele. Isso tem algumas diferenças significativas - o mais importante é que o arquivo ainda está presente para outras pessoas e, se alguém fizer alterações nele e você puxar, sua cópia local poderá ser substituída sem confirmação.
— Soren Bjornstad 22/10/19

8

As respostas acima não funcionaram para mim. Eu costumava filter-branchremover todos os arquivos confirmados.

Remova um arquivo de um repositório git com:

git filter-branch --tree-filter 'rm  file'

Remova uma pasta de um repositório git com:

git filter-branch --tree-filter 'rm -rf directory'

Isso remove o diretório ou arquivo de todas as confirmações.

Você pode especificar uma confirmação usando:

git filter-branch --tree-filter 'rm -rf directory' HEAD

Ou um intervalo:

git filter-branch --tree-filter 'rm -rf vendor/gems' t49dse..HEAD

Para enviar tudo para o controle remoto, você pode:

git push origin master --force

2
Isto combinado com git rm -r --cached NAMEé o truque para removê-lo de seu repositório git local e impedi-lo de afetar qualquer um que puxa mais tarde (por excluir o histórico do arquivo ou diretório a partir do git.)
— notbad.jpeg

1
Isso reescreve a história do git e você precisaria pressionar --force depois, isso está um pouco fora do escopo com a pergunta que eu acho. Em um repositório público famoso, você não pode simplesmente mudar a linha da história dessa maneira, pois todos os que já clonaram o repositório teriam problemas ao puxar.
— Guillaume Perrot #

0

Ignore os arquivos, remova os arquivos do git, atualize o git (para a remoção).

Nota: isso não trata do histórico de informações confidenciais.

Esse processo definitivamente requer alguma compreensão do que está acontecendo com o git. Com o tempo, tendo conseguido isso, aprendi a executar processos como:

1) Ignore os arquivos

  • Adicione ou atualize o projeto .gitignorepara ignorá-los - em muitos casos, como o seu, o diretório pai, por exemplolog/ será o regex a ser usado.
  • confirmar e enviar por push a .gitignorealteração do arquivo (não tenho certeza se o envio é necessário, lembre-se, nenhum dano será feito).

2) Remova os arquivos do git (apenas).

  • Agora remova os arquivos do git (apenas) com git remove --cached some_dir/
  • Verifique se eles ainda permanecem localmente (deveriam!).

3) Adicione e confirme essa alteração (essencialmente, essa é uma alteração para "adicionar" para excluir itens, apesar do comando "adicionar" confuso de outra forma!)

  • git add .
  • git commit -m"removal"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.