Git LFS: versionando arquivos grandes

1. O Problema dos Arquivos Grandes no Git

O Git foi projetado para versionar arquivos de texto e código-fonte, não para lidar com binários pesados. Quando um arquivo grande (como um vídeo de 500 MB ou um dataset de 1 GB) é adicionado ao repositório, o Git armazena cada versão completa desse arquivo no histórico. O resultado é um inchaço acelerado do repositório, lentidão em clones e fetches, e um crescimento descontrolado da pasta .git.

Cenários comuns que sofrem com essa limitação incluem:

  • Assets de jogos (modelos 3D, texturas, áudio)
  • Datasets científicos e de machine learning
  • Vídeos e arquivos multimídia
  • Bibliotecas compiladas e dependências binárias
  • Arquivos de design (PSD, AI, Sketch)

Um repositório com 10 versões de um arquivo de 200 MB teria mais de 2 GB de dados armazenados, tornando o clone inicial extremamente lento e o uso de armazenamento local ineficiente.

2. O que é Git LFS e Como Funciona

Git LFS (Large File Storage) substitui arquivos grandes por ponteiros (pointer files) no repositório Git. Esses ponteiros são arquivos de texto pequenos (cerca de 1 KB) que apontam para o objeto real armazenado em um servidor externo dedicado.

Quando você executa git add, git commit e git push, o Git LFS intercepta automaticamente os arquivos rastreados, envia o conteúdo real para o servidor LFS e armazena apenas o ponteiro no repositório Git. Durante o git pull ou git clone, os ponteiros são baixados normalmente, e os arquivos reais são obtidos sob demanda do servidor LFS.

Para o desenvolvedor, o fluxo de trabalho diário permanece o mesmo: você continua usando git add, git commit, git push e git pull como sempre fez. A diferença é que o Git LFS gerencia os arquivos grandes de forma transparente, mantendo o repositório enxuto.

3. Instalação e Configuração Inicial

Instalação do cliente Git LFS

Linux (Ubuntu/Debian):

sudo apt install git-lfs

macOS (Homebrew):

brew install git-lfs

Windows:
Baixe o instalador em https://git-lfs.com ou use:

choco install git-lfs

Ativação global no sistema

Após instalar, execute uma vez para ativar o Git LFS em todo o sistema:

git lfs install

Esse comando configura hooks do Git e registra o filtro LFS globalmente.

Configuração do servidor remoto

Git LFS funciona com a maioria dos provedores Git modernos. Para habilitar em um repositório existente:

GitHub: O LFS está disponível em todos os planos, com limites de armazenamento e largura de banda conforme o plano.

GitLab: Suporte nativo ao LFS, ativado por projeto nas configurações.

Bitbucket: Suporte ao LFS em planos pagos.

Self-hosted: Você pode configurar seu próprio servidor LFS usando soluções como o GitLab CE ou o pacote git-lfs-authenticate.

4. Rastreando Arquivos Grandes com git lfs track

Para começar a rastrear arquivos grandes, use o comando git lfs track com padrões de arquivo:

git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "assets/**/*.bin"

Isso cria ou atualiza o arquivo .gitattributes na raiz do repositório. Verifique o conteúdo gerado:

cat .gitattributes

Exemplo de saída:

*.psd filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
assets/**/*.bin filter=lfs diff=lfs merge=lfs -text

Para listar os padrões ativos:

git lfs track

Para verificar quais arquivos estão sendo rastreados pelo LFS no repositório:

git lfs ls-files

Lembre-se de commitar o arquivo .gitattributes para que todos os colaboradores usem as mesmas regras:

git add .gitattributes
git commit -m "Configura LFS para arquivos PSD, MP4 e binários"

5. Fluxo de Trabalho com Git LFS

Adicionando, commitando e enviando

O fluxo é idêntico ao Git normal:

git add arquivo_grande.psd
git commit -m "Adiciona arquivo PSD de design"
git push origin main

O Git LFS automaticamente detecta que o arquivo corresponde a um padrão rastreado e gerencia o upload para o servidor LFS. Durante o push, você verá mensagens como:

Uploading LFS objects: 100% (1/1), 245 MB | 5.2 MB/s

Clonando repositórios com LFS

O comando tradicional git clone baixa os ponteiros LFS, mas não os arquivos reais. Para baixar tudo de uma vez:

git clone https://github.com/usuario/repositorio.git
git lfs pull

Ou use o comando otimizado (disponível em versões mais antigas do LFS):

git lfs clone https://github.com/usuario/repositorio.git

Pull de arquivos LFS sob demanda

Para baixar apenas os arquivos LFS do checkout atual:

git lfs pull

Se você quiser baixar arquivos LFS específicos sem fazer checkout:

git lfs pull --include="*.psd"

6. Gerenciamento e Manutenção

Verificando arquivos LFS no repositório

Para listar todos os arquivos LFS em todas as branches e tags:

git lfs ls-files --all

Para ver o tamanho total dos objetos LFS:

git lfs ls-files --all --size

Removendo arquivos do rastreamento LFS

Para parar de rastrear um padrão:

git lfs untrack "*.psd"

Isso remove a entrada do .gitattributes, mas não afeta arquivos já commitados com LFS. Cuidado: remover o rastreamento não remove os objetos LFS do histórico. Para isso, seria necessário reescrever o histórico com git lfs migrate.

Limpeza de cache local

Com o tempo, o cache local do LFS pode acumular objetos não utilizados. Para liberar espaço:

git lfs prune

Esse comando remove objetos LFS locais que não são referenciados por nenhum commit recente.

7. Boas Práticas e Limitações

O que versionar com LFS

  • Sim: Assets binários grandes (imagens, áudio, vídeo), datasets, arquivos de design, bibliotecas compiladas, arquivos de jogo.
  • Não: Código-fonte, arquivos de configuração, documentos de texto pequenos, dependências gerenciadas por package managers.

Limites de largura de banda e armazenamento

Cada provedor tem seus limites:

  • GitHub Free: 2 GB de armazenamento, 1 GB de largura de banda por mês.
  • GitLab Free: 5 GB de armazenamento.
  • Bitbucket Free: 1 GB de armazenamento.

Planos pagos aumentam esses limites. Para projetos com muitos arquivos grandes, considere o custo operacional.

Migração de repositórios existentes

Para migrar um repositório que já contém arquivos grandes para LFS, use:

git lfs migrate import --include="*.psd,*.mp4" --everything

Esse comando reescreve o histórico, substituindo os arquivos grandes por ponteiros LFS. Aviso: isso altera hashes de commits e deve ser coordenado com toda a equipe.

Resolução de conflitos em arquivos LFS

Arquivos binários rastreados pelo LFS não podem ter merge automático. Se dois desenvolvedores modificarem o mesmo arquivo LFS, ocorrerá um conflito que deve ser resolvido manualmente, geralmente escolhendo uma versão ou usando ferramentas externas.

8. Comparação com Alternativas e Considerações Finais

Git LFS vs. Git Submodules

  • Git Submodules: Permite incluir outros repositórios Git dentro do seu projeto. Útil para bibliotecas com versionamento independente, mas não resolve o problema de arquivos grandes.
  • Git LFS: Focado exclusivamente em substituir arquivos grandes por ponteiros, mantendo o fluxo Git tradicional.

Git LFS vs. Git Annex

  • Git Annex: Solução mais flexível que permite armazenar arquivos em múltiplos locais remotos (S3, rsync, etc.). Mais complexo de configurar e usar.
  • Git LFS: Mais simples e integrado, mas depende de um servidor LFS dedicado.

Quando usar cada abordagem

  • Use Git LFS quando você precisa de simplicidade e integração direta com provedores Git (GitHub, GitLab).
  • Use Git Annex quando precisa de controle granular sobre onde os arquivos são armazenados ou quando trabalha com datasets enormes que não cabem em servidores LFS tradicionais.
  • Use armazenamento externo (S3, CDN) para arquivos que não precisam de versionamento, como builds finais ou assets de produção.

Resumo do impacto

Git LFS resolve o problema de repositórios inchados sem alterar drasticamente o fluxo de trabalho dos desenvolvedores. A equipe continua usando os mesmos comandos Git, mas com a garantia de que arquivos grandes não poluirão o histórico. O custo é a dependência de um servidor LFS e limites de armazenamento/largura de banda, que devem ser monitorados.

Para times que trabalham com assets pesados, datasets ou qualquer tipo de binário que precisa de versionamento, Git LFS é a ferramenta padrão da indústria e a recomendação mais prática.

Referências