Git LFS: gerenciando arquivos binários e assets grandes no repositório

1. Introdução ao Git LFS e o problema de arquivos grandes

Repositórios Git tradicionais foram projetados para arquivos de texto e código-fonte. Quando você adiciona binários — texturas de jogos, arquivos PSD, datasets de machine learning, vídeos ou modelos 3D — o repositório incha rapidamente. Cada versão de um arquivo binário de 500 MB é armazenada integralmente, resultando em clones lentos, uso excessivo de disco e operações como git log e git diff se tornando impraticáveis.

O Git LFS (Large File Storage) resolve isso substituindo arquivos grandes por pequenos arquivos de ponteiro (pointers) no repositório principal. O conteúdo real é armazenado em um servidor separado (GitHub, GitLab, Bitbucket ou servidor próprio). Quando você clona ou faz checkout, o LFS baixa apenas os arquivos necessários, sob demanda.

Casos de uso típicos incluem:
- Desenvolvimento de jogos (texturas, modelos 3D, áudio)
- Design gráfico (arquivos PSD, AI, Sketch)
- Produção audiovisual (arquivos de vídeo, áudio masterizado)
- Machine learning (datasets, modelos treinados)

2. Instalação e configuração inicial do Git LFS

A instalação varia conforme o sistema operacional:

# Linux (Debian/Ubuntu)
sudo apt install git-lfs

# macOS
brew install git-lfs

# Linux (Fedora/RHEL)
sudo dnf install git-lfs

Após instalar, ative o LFS globalmente:

git lfs install

Para configurar em um repositório específico, navegue até ele e defina os padrões de arquivo a serem rastreados:

cd meu-projeto
git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "assets/textures/*.png"

Isso cria ou atualiza o arquivo .gitattributes na raiz do repositório. Você deve versioná-lo:

git add .gitattributes
git commit -m "Configura Git LFS para arquivos PSD, MP4 e texturas"

O conteúdo do .gitattributes será algo como:

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

3. Comandos essenciais do dia a dia com Git LFS

Rastreando e removendo padrões:

# Adicionar padrão
git lfs track "*.zip"

# Remover padrão (não remove arquivos já rastreados)
git lfs untrack "*.zip"

# Ver padrões ativos
git lfs track

Inspecionando arquivos gerenciados:

# Ver status dos arquivos LFS
git lfs status

# Listar arquivos rastreados
git lfs ls-files

# Ver detalhes de um arquivo específico
git lfs ls-files --long

Baixando conteúdo:

# Baixar todos os arquivos LFS para o checkout atual
git lfs pull

# Apenas baixar objetos sem extrair
git lfs fetch

# Baixar objetos de um commit específico
git lfs fetch --all

4. Fluxo de trabalho com Git LFS em equipes

Clonagem inicial:

# Clone normal já funciona com LFS (desde que git lfs install foi executado)
git clone https://github.com/usuario/repositorio.git

# Alternativa (obsoleta em versões recentes, mas ainda funcional)
git lfs clone https://github.com/usuario/repositorio.git

Em versões recentes do Git (2.20+), git clone já integra o LFS automaticamente.

Pull requests e merge:

Conflitos em binários LFS são raros, mas quando ocorrem, o Git LFS mantém ambas as versões. A resolução é manual — você escolhe qual versão manter. Não há merge automático de binários.

Boas práticas:

  • Não rastreie arquivos pequenos (< 100 KB) com LFS — o overhead não compensa.
  • Use .gitignore complementar para excluir arquivos temporários e caches.
  • Evite rastrear diretórios inteiros sem critério — seja específico nos padrões.
# Exemplo de .gitignore complementar
*.tmp
*.cache
node_modules/

5. Gerenciamento de armazenamento e limites no servidor

Limites por plataforma (valores típicos):

  • GitHub: 1 GB de armazenamento gratuito, 1 GB de banda/mês (planos pagos aumentam)
  • GitLab: 5 GB por projeto no plano gratuito
  • Bitbucket: 1 GB de armazenamento, 1 GB de banda/mês

Migrando histórico para LFS:

Se você já tem commits com arquivos grandes, use git lfs migrate para reescrever o histórico:

# Migrar todos os arquivos .psd do histórico
git lfs migrate import --include="*.psd"

# Migrar arquivos acima de 10 MB
git lfs migrate import --everything --above=10MB

Limpando objetos órfãos:

# Remover objetos LFS não referenciados por commits locais
git lfs prune

# Deduplicar objetos idênticos
git lfs dedup

6. Integração com CI/CD e automação

GitHub Actions:

No workflow, habilite o LFS no checkout:

- name: Checkout com LFS
  uses: actions/checkout@v4
  with:
    lfs: true

Cache de arquivos LFS em pipelines:

- name: Cache LFS objects
  uses: actions/cache@v3
  with:
    path: .git/lfs/objects
    key: lfs-${{ hashFiles('.gitattributes') }}

Estratégias para build/deploy:

  • Faça git lfs pull apenas dos arquivos necessários para o build.
  • Considere usar git lfs fetch --include="*.unity3d" para baixar seletivamente.
  • Em deploys, mantenha os pointers no repositório e baixe os binários apenas no servidor de produção.

7. Debug, troubleshooting e recuperação de problemas

Erro comum: "batch response: Repository or object not found"

Causa: o servidor LFS não tem o objeto referenciado. Solução:

# Verificar integridade
git lfs fsck

# Verificar objetos locais
git lfs verify

# Forçar download de objetos ausentes
git lfs fetch --all

Timeouts em arquivos muito grandes:

Aumente o timeout do Git:

git config lfs.http://<servidor>.com/timeout 600

Recuperação de pointers corrompidos:

# Reconstruir pointers a partir do conteúdo real
git lfs migrate export --include="*.psd"

8. Alternativas e limitações do Git LFS

Alternativas:

  • Git Annex: mais flexível, permite armazenar arquivos em múltiplos locais (S3, rsync, etc.), mas mais complexo.
  • DVC (Data Version Control): focado em datasets de ML, integra com S3/GCS/SSH, melhor para pipelines de dados.
  • Armazenamento externo simples: usar scripts para baixar assets de um bucket S3 durante o build.

Limitações do Git LFS:

  • Sem diff automático de binários (você não vê o que mudou entre versões).
  • Dependência de servidor LFS — sem ele, os pointers são inúteis.
  • Complexidade em forks: quem faz fork precisa ter acesso ao servidor LFS original.
  • Não recomendado para: arquivos pequenos que mudam frequentemente, repositórios com muitos contribuidores esporádicos, equipes sem acesso confiável ao servidor LFS.

Referências