Eu estava trabalhando em um repositório na minha conta do GitHub e esse é um problema que me deparei.
- Projeto Node.js com uma pasta com alguns pacotes npm instalados
- Os pacotes estavam na
node_modules
pasta - Adicionada a pasta ao repositório git e empurrou o código para o github (não estava pensando na parte npm naquela época)
- Percebeu que você realmente não precisa dessa pasta para fazer parte do código
- Excluiu essa pasta, empurrou-a
Nesse caso, o tamanho do repositório Git total era de cerca de 6 MB, enquanto o código real (todos, exceto a pasta) era de apenas 300 KB .
Agora, o que estou procurando no final é uma maneira de livrar-se dos detalhes dessa pasta de pacotes do histórico do git; portanto, se alguém o clona, ele não precisa fazer o download de 6mb no histórico, onde os únicos arquivos reais serão recuperados a partir do último commit seria 300 KB.
Procurei possíveis soluções para isso e tentei esses 2 métodos
- Remover arquivo do repositório git (histórico)
- http://help.github.com/remove-sensitive-data/
- https://gist.github.com/1588371
O Gist parecia que funcionava onde, depois de executar o script, mostrava que ele se livrava dessa pasta e depois mostrava que 50 commits diferentes foram modificados. Mas isso não me deixou levar esse código. Quando tentei empurrá-lo, ele disse, Branch up to date
mas mostrou que 50 commits foram modificados em a git status
. Os outros 2 métodos também não ajudaram.
Agora, apesar de mostrar que se livrou do histórico dessa pasta, quando verifiquei o tamanho desse repositório no meu host local, ele ainda estava em torno de 6 MB. (Também excluí a refs/original
pasta, mas não vi a alteração no tamanho do repositório).
O que pretendo esclarecer é que, se existe uma maneira de se livrar não apenas do histórico de consolidação (que é a única coisa que acho que aconteceu), mas também daqueles arquivos que o git continua assumindo que se deseja reverter.
Vamos dizer que uma solução é apresentada para isso e aplicada no meu host local, mas não pode ser reproduzida no repositório GitHub, é possível cloná-lo, a reversão para o primeiro commit executa o truque e o pressiona (ou isso significa que o git irá ainda tem um histórico de todos esses commits? - também conhecido como 6MB).
Meu objetivo final aqui é basicamente encontrar a melhor maneira de livrar-se do conteúdo da pasta do git, para que um usuário não precise baixar 6MB de material e ainda possua os outros commits que nunca tocaram na pasta modules (isso é bastante todos eles) na história do git.
Como posso fazer isso?
fonte
Respostas:
Se você está aqui para copiar e colar o código:
Este é um exemplo que remove
node_modules
do históricoO que o git realmente faz:
A primeira linha percorre todas as referências na mesma árvore (
--tree-filter
) que HEAD (sua ramificação atual), executando o comandorm -rf node_modules
. Este comando exclui a pasta node_modules (-r
sem-r
,rm
não exclui pastas), sem nenhum aviso ao usuário (-f
). As--prune-empty
exclusões excluídas são inúteis (sem alterar nada) confirmam recursivamente.A segunda linha exclui a referência a esse ramo antigo.
O restante dos comandos é relativamente direto.
fonte
git count-objects -v
verificar se os arquivos foram realmente removidos, mas o tamanho do repositório permanece o mesmo até que eu clonei o repositório novamente. Git mantém uma cópia de todos os arquivos originais, eu acho.--force-with-lease
, não--force
.Acho que a
--tree-filter
opção usada em outras respostas pode ser muito lenta, especialmente em repositórios maiores com muitos commits.Aqui está o método que eu uso para remover completamente um diretório do histórico do git usando a
--index-filter
opção, que é executada muito mais rapidamente:Você pode verificar o tamanho do repositório antes e depois do
gc
com:fonte
--quiet
aogit rm
acima acelerou minha reescrita pelo menos pelo fator 4.Além da resposta popular acima , gostaria de adicionar algumas notas para os sistemas Windows . O comando
funciona perfeitamente sem qualquer modificação! Portanto, você não deve usar
Remove-Item
,del
ou qualquer outra coisa em vez derm -rf
.Se você precisar especificar um caminho para um arquivo ou diretório, use barras como
./path/to/node_modules
fonte
O melhor e mais preciso método que encontrei foi fazer o download do arquivo bfg.jar: https://rtyley.github.io/bfg-repo-cleaner/
Em seguida, execute os comandos:
Se você deseja excluir arquivos, use a opção delete-files:
fonte
Parece que a resposta atualizada para isso é não usar
filter-branch
diretamente (pelo menos o próprio git não o recomenda mais) e adiar esse trabalho para uma ferramenta externa. Em particular, o git-filter-repo é atualmente recomendado. O autor dessa ferramenta fornece argumentos sobre por que usarfilter-branch
diretamente pode levar a problemas.A maioria dos scripts de várias linhas acima para remover
dir
do histórico pode ser reescrita como:A ferramenta é mais poderosa do que apenas isso, aparentemente. Você pode aplicar filtros por autor, email, refname e mais (página de manual completa aqui ). Além disso, é rápido . A instalação é fácil - é distribuída em uma variedade de formatos .
fonte
pip3 install git-filter-repo
porque é apenas stdlib e não instala nenhuma dependência. No Ubuntu 18 é incompatível com a versão git da distroError: need a version of git whose diff-tree command has the --combined-all-paths option
, mas é fácil o suficiente para executá-la em umdocker run -ti ubuntu:20.04
Receita completa de copiar e colar, apenas adicionando os comandos nos comentários (para a solução copiar e colar), depois de testá-los:
Depois disso, você pode remover a linha "node_modules /" de .gitignore
fonte
node_modules
de.gitignore
? Para que eles possam ser acidentalmente cometidos novamente?node_modules
de.gitignore
.Para usuário do Windows, observe o uso em
"
vez de'
Também adicionado-f
para forçar o comando se outro backup já estiver lá.fonte
Eu removi as pastas bin e obj de projetos antigos de C # usando o git no Windows. Tenha cuidado com
Destrói a integridade da instalação do git excluindo a pasta usr / bin na pasta de instalação do git.
fonte