Para encontrar os maiores arquivos armazenados no histórico acessível do Git de um repositório no macOS, abra o Terminal, navegue até o repositório e passe a lista de objetos do Git por pipe para git cat-file e sort. Isso informa o tamanho descompactado de cada blob em bytes e uma dica de caminho. Isso pode revelar arquivos que foram excluídos ou substituídos, mas continuam em commits acessíveis a partir de branches ou tags.

Execute uma varredura de histórico a partir do Terminal

No Terminal, use cd para entrar no repositório. Coloque o caminho da pasta entre aspas se ele contiver espaços. Em seguida, execute:

git rev-list --objects --all |
  git cat-file --batch-check='%(objecttype) %(objectsize) %(objectname) %(rest)' |
  awk '$1 == "blob"' |
  sort -k2,2nr |
  head -20

A saída é ordenada do maior para o menor. Cada linha mostra o tipo de objeto, a contagem de bytes, o ID do objeto e, quando o Git fornece uma, uma dica de caminho. O comando git rev-list --objects --all percorre os objetos referenciados por commits acessíveis a partir de referências (refs), como branches e tags locais; git cat-file --batch-check informa o tipo e o tamanho de cada objeto. O pipeline filtra por blobs, os objetos que contêm o conteúdo dos arquivos. A documentação do rev-list do Git descreve a navegação e os nomes dos objetos, e a do cat-file documenta a saída em lote de tamanhos e tipos.

O comando sort -k2,2nr usa o utilitário sort nativo do macOS para ordenar numericamente em ordem decrescente pelo segundo campo separado por espaços, que é o tamanho em bytes. head -20 limita a exibição a 20 linhas; altere o número ou remova essa última linha para ver mais. O comando apenas lê dados do repositório. Ele não modifica commits ou arquivos.

Interprete os resultados com cuidado

Uma linha identifica um objeto blob, não necessariamente um arquivo presente no momento na árvore de trabalho (working tree). Um objeto grande pode ser proveniente de uma versão antiga de um arquivo, e uma dica de caminho não é um índice histórico completo de caminhos: a documentação do Git ressalta que, com --objects, os nomes são apenas sugestões, podem ser alterados devido a quebras de linha e, quando um objeto possui múltiplos nomes, apenas um pode ser exibido. Trate o caminho listado como uma pista e, em seguida, inspecione os commits relevantes para confirmar quando e onde o conteúdo apareceu. As notas sobre nomes de objetos no rev-list do Git explicam essas limitações.

Esta varredura abrange objetos acessíveis a partir de refs descobertas por --all, não todos os objetos que podem permanecer fisicamente no banco de dados de objetos. Para verificar o armazenamento local de objetos, incluindo objetos inacessíveis, execute:

git cat-file --batch-all-objects \
  --batch-check='%(objecttype) %(objectsize) %(objectname)' |
  awk '$1 == "blob"' |
  sort -k2,2nr |
  head -20

--batch-all-objects visita todos os objetos no repositório e em armazenamentos de objetos alternativos, incluindo objetos que não são acessíveis a partir de refs. Este segundo comando omite os caminhos de arquivos; portanto, use o ID do objeto para investigar mais a fundo. A documentação do cat-file observa tanto a abrangência maior de objetos quanto o fato de que cada objeto é mostrado apenas uma vez, mesmo se estiver armazenado repetidas vezes.

O tamanho do blob não é o mesmo que o espaço em disco

O valor objectsize informado é o tamanho descompactado de um objeto Git. O Git pode compactar objetos ou armazená-los como deltas dentro de arquivos de pacote (packfiles), portanto um blob grande não consome necessariamente essa quantidade exata de disco. Para uma visão geral do uso de armazenamento, execute git count-objects -vH; o campo size-pack relata o tamanho dos dados empacotados e seus outros campos resumem objetos soltos (loose objects) e o armazenamento relacionado. O manual do count-objects do Git documenta esses números. Para inspecionar tamanhos de objetos empacotados e detalhes de deltas, git verify-pack -v lista o tamanho de cada objeto empacotado e seu tamanho dentro do packfile, mas exige o arquivo .idx correspondente. O manual do verify-pack define essa saída.

Se você encontrar um arquivo histórico grande

Primeiro, decida se a sua tarefa é entender o checkout atual ou reduzir o histórico do repositório. Apenas para a versão atual, inspecione os arquivos no Finder ou use uma listagem de tamanho de arquivo no Terminal; a varredura do histórico responde a uma pergunta diferente ao pesquisar objetos Git acessíveis.

Se um arquivo grande deve ser removido de todas as revisões, excluí-lo apenas em um novo commit não apagará as cópias mais antigas do histórico. A reescrita de histórico altera os IDs de commit e afeta outras pessoas que usam o repositório; portanto, coordene a ação antes de executá-la e mantenha um backup. O projeto git-filter-repo oferece um modo de análise somente leitura, git filter-repo --analyze, que gera relatórios para ajudar a decidir o que filtrar; ele não executa a reescrita no modo de análise. A documentação do projeto descreve a opção de análise e alerta que a filtragem reescreve o histórico.

O primeiro pipeline é o ponto de partida prático quando o objetivo é encontrar os maiores conteúdos de arquivos no histórico de um repositório local. Use a varredura de todos os objetos quando sobras inacessíveis forem importantes, e compare os tamanhos dos objetos Git com o armazenamento empacotado antes de atribuir o uso de disco a um blob específico.

Fontes