Eu acidentalmente adicionei, enviei e enviei um enorme arquivo binário com meu último commit para um repositório Git.
Como posso fazer o Git remover o (s) objeto (s) que foi / foram criados para esse commit para que meu .git
diretório diminua para um tamanho normal novamente?
Edit : Obrigado por suas respostas; Tentei várias soluções. Nenhum funcionou. Por exemplo, o do GitHub removeu os arquivos do histórico, mas o .git
tamanho do diretório não diminuiu:
$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)
$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten
$ git log -p # looks nice
$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)
$ du -hs .git
174M .git
$ # still 175 MB :-(
git-repack -a
seguido por,git-prune-packed
por exemplo. Veja blog.felipebalbi.com/2007/12/19/…filter-branch
,gc
,repack
, ...), não, você não deve ver qualquer mau cometer em tudo. Isso é um sinal de que a limpeza não ocorreu conforme o esperado.Respostas:
Eu respondi isso em outro lugar, e vou copiar aqui, pois tenho orgulho disso!
... e sem mais delongas, posso apresentar a você este script útil, git-gc-all, garantido para remover todo o seu lixo git até que eles possam vir com variáveis de configuração extras:
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \ -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \ -c gc.pruneExpire=now gc "$@"
A opção --aggressive pode ser útil.
NOTA: isso removerá TODAS as coisinhas não referenciadas, então não venha chorar para mim se você decidir mais tarde que deseja manter algumas delas!
Você também pode precisar executar algo assim primeiro, oh querido, git é complicado !!
git remote rm origin rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/ git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --no-run-if-empty git update-ref -d
Coloquei tudo isso em um script, aqui:
http://sam.nipl.net/b/git-gc-all-ferocious
fonte
xargs
comando produz um erro no OS X por causa de uma opção não reconhecida. Solução mais simples: Instale o GNU xargs via homebrewbrew install findutils
e substituaxargs
porgxargs
.Seu
git reflog expire --all
está incorreto. Ele remove as entradas de reflog mais antigas do que o tempo de expiração, cujo padrão é 90 dias. Usegit reflog expire --all --expire=now
.Minha resposta a uma pergunta semelhante trata do problema de realmente limpar objetos não utilizados de um repositório.
fonte
1) Remova o arquivo do repo git (e não do sistema de arquivos):
git rm --cached path/to/file
2) Reduza o repo usando:
git gc
,ou
git gc --aggressive
git prune
ou uma combinação das opções acima, conforme sugerido nesta pergunta: Reduza o tamanho do repositório git
fonte
Este guia sobre a remoção de dados confidenciais pode ser aplicado, usando o mesmo método. Você estará reescrevendo o histórico para remover esse arquivo de todas as revisões em que ele estava presente. Isso é destrutivo e causará conflitos de repo com quaisquer outros checkouts, então avise os colaboradores primeiro.
Se você deseja manter o binário disponível no repo para outras pessoas, não há uma maneira real de fazer o que você deseja. É quase tudo ou nada.
fonte
A chave para mim acabou sendo executar
git repack -A -d -f
egit gc
reduzir o tamanho do pacote git único que eu tinha.fonte
Hy!
Git só recebe objetos de que realmente precisa ao clonar repositórios (se bem entendi)
Então você pode corrigir o último commit removendo o arquivo adicionado por engano, então enviar suas alterações para o repositório remoto (com a opção -f para sobrescrever o commit antigo no servidor também)
Então, quando você fizer um novo clone desse repo, seu diretório .git deverá ser tão pequeno quanto antes dos arquivos grandes enviados.
Opcionalmente, se você deseja remover os arquivos desnecessários do servidor também, você pode excluir o repositório no servidor e enviar sua cópia recém-clonada (que tem o histórico completo)
fonte
Lembre-se de mudar
Filename
para aquele que você deseja remover do repositório.fonte
Consulte "Removendo objetos" no livro Pro Git:
http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects
Atualização: veja também limpador de repositório BFG: http://rtyley.github.io/bfg-repo-cleaner/
fonte
Em 2020, a documentação para git-filter-branch desencoraja seu uso e recomenda o uso de uma alternativa como git-filter-repo . Ele também pode ser usado no lugar do BFG .
Observe que o capítulo sobre Reescrevendo o histórico no livro git não foi atualizado. Nem a recomendação do GitHub sobre a remoção de dados confidenciais.
fonte