Fundamentos

Git LFS: como guardar arquivos grandes num repositório Git

Atualizado: · Skillaria.Top

O Git LFS (Large File Storage) é uma extensão do Git que guarda arquivos binários grandes num servidor separado e coloca no repositório apenas pequenos arquivos-ponteiro. O clone fica rápido, o histórico não incha e o trabalho com os arquivos continua o mesmo de sempre: git add, commit e push.

O que é o Git LFS e para que serve

O Git LFS (Large File Storage) é a extensão oficial do Git para guardar arquivos grandes: vídeos, layouts PSD, datasets, modelos de redes neurais, assets de jogos. Em vez do próprio arquivo, o commit recebe um ponteiro de texto de cerca de 130 bytes, e o conteúdo vai para um armazenamento LFS separado no servidor. No checkout, a extensão coloca o arquivo real na pasta de trabalho, então para você tudo parece o Git normal.

O problema que o git lfs resolve está na própria estrutura do Git. Cada versão de cada arquivo fica para sempre no histórico, e o clone baixa o histórico inteiro. Se você alterou dez vezes um vídeo de 200 MB, o repositório já pesa cerca de 2 GB, e cada novo desenvolvedor baixa as dez versões, mesmo que só precise da última. A compressão e as deltas, que funcionam bem para texto, são quase inúteis em arquivos binários.

Com o LFS, o clone baixa só as versões dos arquivos grandes do commit atual. As versões antigas ficam no servidor e são baixadas quando você muda para um commit antigo.

Como o Git LFS funciona por dentro

O mecanismo se baseia nos filtros do Git — clean e smudge. Quando você faz git add de um arquivo rastreado pelo LFS, o filtro clean entra em ação: ele coloca o conteúdo no cache local .git/lfs/objects e passa um ponteiro para o índice. No checkout, o filtro smudge faz o contrário: encontra o objeto pelo hash no cache (ou baixa do servidor) e grava o arquivo real.

O ponteiro tem esta cara:

version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 209715200

Três linhas: a versão da especificação, o SHA-256 do conteúdo e o tamanho em bytes. É isso que fica no histórico do Git, e por isso o histórico continua leve. No git push é acionado um hook pre-push: primeiro os novos objetos são enviados pela API do LFS, depois os commits vão pelo protocolo normal.

Quais arquivos vão para o LFS é definido pelo arquivo .gitattributes na raiz do repositório. Ele é commitado junto com o código, então as regras são as mesmas para todo o time.

Como instalar o Git LFS

No Git para Windows, a extensão já vem no instalador. No macOS e no Linux, ela é instalada como pacote:

# macOS (Homebrew)
brew install git-lfs

# Debian / Ubuntu
sudo apt install git-lfs

# Fedora
sudo dnf install git-lfs

Depois da instalação, execute uma vez por usuário:

git lfs install

O comando registra os filtros do LFS no ~/.gitconfig global e instala os hooks no repositório atual, se você estiver dentro dele. Para conferir se está tudo certo, use git lfs version; a configuração detalhada (endereço do servidor, caminhos do cache) aparece com git lfs env.

Como começar a rastrear arquivos grandes

Cenário típico para um projeto novo:

git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "models/**"

git add .gitattributes
git add design/banner.psd
git commit -m "Adicionar layout do banner via LFS"
git push origin main

As aspas em volta do padrão são obrigatórias: sem elas, o shell expande *.psd para a lista de arquivos da pasta atual e a regra sai errada. Depois do git lfs track, aparece no .gitattributes a linha:

*.psd filter=lfs diff=lfs merge=lfs -text

O atributo -text desativa a conversão de quebras de linha, que estragaria um arquivo binário. A ordem importa: primeiro a regra de track, depois o git add do arquivo. Se o arquivo já tinha sido adicionado do jeito normal antes da regra existir, ele ficou no histórico como um blob comum.

Como conferir se o arquivo está mesmo no LFS

git lfs ls-files
4d7a214614 * design/banner.psd
9c1e0b7a3f * video/intro.mp4

git lfs status

git lfs ls-files mostra os arquivos do commit atual guardados no LFS. O asterisco indica que o conteúdo foi baixado; o hífen, que na cópia de trabalho há só o ponteiro. A lista de padrões rastreados aparece com git lfs track sem argumentos, e uma regra pode ser removida com git lfs untrack "*.psd".

Clonar e obter os arquivos

O git clone comum trabalha com o LFS de forma transparente: se a extensão está instalada, os arquivos grandes são baixados automaticamente. Já se um colega não tem o LFS instalado, ele verá na cópia de trabalho os ponteiros de texto no lugar das imagens — é o sintoma mais comum de "no lugar do meu PSD tem um texto qualquer". A solução é instalar e executar:

git lfs install
git lfs pull

git lfs pull baixa os objetos do commit atual e os coloca na pasta de trabalho. Existe também o git lfs fetch, que só baixa para o cache, sem mexer nos arquivos. Com a flag --all, ele baixa os objetos de todas as referências, o que é útil para um backup completo ou para migrar para outro servidor.

Como clonar sem os arquivos grandes

No CI, ou quando você só precisa do código, baixar gigabytes de assets é desperdício. Uma variável de ambiente desativa o filtro smudge:

GIT_LFS_SKIP_SMUDGE=1 git clone https://example.com/team/game.git
cd game
git lfs pull --include="textures/ui/**"

O repositório é clonado com os ponteiros e, depois, você baixa seletivamente os arquivos necessários com --include (também existe --exclude). Isso acelera bastante os builds nos pipelines.

Como migrar arquivos existentes para o Git LFS

Situação frequente: o repositório já está inchado, com arquivos grandes no histórico. O comando git lfs track não age sobre o passado — só afeta commits novos. Para reescrever o histórico, use git lfs migrate.

Primeiro, veja o que ocupa espaço:

git lfs migrate info --everything --top=10

Depois, migre os tipos desejados em todas as branches:

git lfs migrate import --include="*.psd,*.mp4" --everything
git push --force --all
git push --force --tags

A migração reescreve cada commit em que esses arquivos aparecem, então todos os hashes mudam. É a mesma história do rebase de branches publicadas: todos os participantes precisam ser avisados e, depois do push forçado, devem clonar o repositório de novo ou redefinir suas branches com força. Antes da migração, faça um backup (git clone --mirror).

Se não é possível reescrever o histórico, existe uma opção mais suave: git lfs migrate import --no-rewrite caminho/do/arquivo. Ela cria um novo commit que passa os arquivos para o LFS a partir daquele ponto. As versões antigas continuam no histórico, mas o repositório para de crescer.

Bloqueio de arquivos: proteção contra conflitos em binários

Dois designers editam o mesmo PSD — e o Git não consegue mesclar as alterações deles; um dos trabalhos será perdido. Para esses arquivos, o LFS tem bloqueios. Marque o tipo como bloqueável:

git lfs track "*.psd" --lockable

O atributo lockable é adicionado ao .gitattributes, e esses arquivos ficam somente leitura na cópia de trabalho até você bloqueá-los:

git lfs lock design/banner.psd
git lfs locks
design/banner.psd	anna	ID:123

# depois do push das alterações
git lfs unlock design/banner.psd

Enquanto o arquivo estiver bloqueado, o push de alterações nele feito por outra pessoa será rejeitado. Os bloqueios dependem do servidor, então funcionam nas grandes hospedagens Git, mas podem não existir num servidor próprio. Um administrador pode remover o bloqueio de outra pessoa com git lfs unlock --force.

Onde ficam os objetos LFS e quanto isso custa

Os objetos LFS ficam num servidor que implementa a API do LFS. Ela é suportada pelas hospedagens Git populares e por soluções self-hosted, além de servidores dedicados. As hospedagens na nuvem têm limites de armazenamento e de tráfego LFS, que variam entre serviços e planos — confira as condições atuais da sua plataforma antes de colocar lá datasets de centenas de gigabytes.

Lembre-se de que o tráfego é contado a cada download: um CI que clona o repositório com arquivos LFS a cada commit pode consumir o limite mais rápido que as pessoas. Faça cache do .git/lfs entre os builds ou use GIT_LFS_SKIP_SMUDGE.

Localmente, o cache também cresce. O comando git lfs prune remove objetos antigos que já estão no servidor e não são necessários para os commits atuais e recentes.

Quando o Git LFS é adequado e quando não

SituaçãoO LFS serve?Comentário
Assets de jogos, layouts, áudio, vídeoSimO caso clássico: binários que mudam com frequência
Modelos de ML e datasets médios junto ao códigoSim, de olho nas cotasPara dados muito grandes, ferramentas específicas de versionamento de dados são mais práticas
Artefatos compilados do buildNãoO lugar deles é um registro de artefatos ou os releases, não o Git
Dependências (node_modules, vendor)NãoSão instaladas pelo gerenciador de pacotes; adicione-as ao .gitignore
Arquivos de texto grandes (dumps SQL, CSV)DependeO Git guarda texto de forma eficiente com deltas; o LFS é necessário se os arquivos forem enormes e quase ilegíveis no diff
Segredos e chaves privadasNuncaO LFS não criptografa os dados, não é um cofre de segredos

Erros comuns e como corrigi-los

Na cópia de trabalho aparece um ponteiro de texto em vez do arquivo

O LFS não está instalado ou o clone foi feito com GIT_LFS_SKIP_SMUDGE=1. Execute git lfs install e git lfs pull.

O arquivo entrou no histórico sem passar pelo LFS

A regra de track foi adicionada depois do git add. Se o commit ainda não foi enviado, tire o arquivo do índice (git rm --cached arquivo), confirme que a regra está no .gitattributes e adicione-o de novo. Se já foi enviado, use git lfs migrate import. Para encontrar esses arquivos, ajuda o git lfs fsck --pointers.

O push é rejeitado por causa do tamanho do arquivo

Muitas hospedagens limitam o tamanho de um único objeto no Git comum. Uma mensagem como "this exceeds the file size limit" significa que o arquivo deveria ter ido para o LFS. Reescreva o último commit ou o histórico como descrito acima — um simples commit "apagar arquivo" não resolve, porque o arquivo continua nos commits anteriores.

Depois do git lfs migrate, tudo quebrou para os colegas

As branches locais deles se baseiam nos hashes antigos. O mais seguro é clonar o repositório de novo; se houver trabalho não enviado, leve-o para as novas branches com cherry-pick.

Cola de comandos do Git LFS

ComandoO que faz
git lfs installConfigura filtros e hooks
git lfs track "*.ext"Adiciona um padrão ao .gitattributes
git lfs untrack "*.ext"Remove um padrão
git lfs ls-filesArquivos no LFS do commit atual
git lfs pullBaixar e colocar os objetos no lugar
git lfs fetch --allBaixar para o cache os objetos de todas as referências
git lfs migrate import --include="..." --everythingLevar arquivos do histórico para o LFS
git lfs lock / unlock / locksTrabalhar com bloqueios
git lfs pruneLimpar objetos antigos do cache local
git lfs envDiagnóstico da configuração

Resumo

O Git LFS tira os arquivos binários grandes do histórico e os leva para um armazenamento separado, deixando nos commits ponteiros leves. A regra principal é configurar o git lfs track antes do primeiro commit dos arquivos grandes, commitar o .gitattributes e ficar de olho nas cotas da hospedagem. Se os arquivos já estão no histórico, o git lfs migrate ajuda, mas isso é reescrever o histórico, com todas as consequências. O trabalho com o histórico, rebase e outras ferramentas avançadas do Git é praticado no curso de Git.

Perguntas frequentes

O Git LFS é gratuito?

A extensão em si é aberta e gratuita. Você pode ter de pagar pelo armazenamento e pelo tráfego na hospedagem Git, se ultrapassar os limites gratuitos do seu plano.

Que tamanho de arquivo conta como grande para o LFS?

Não há um limite rígido; normalmente vão para o LFS binários a partir de alguns megabytes que mudam com frequência. Arquivos de texto, mesmo grandes, o Git guarda de forma eficiente sem LFS.

Dá para abandonar o Git LFS e devolver os arquivos ao Git comum?

Sim, com o comando git lfs migrate export --include="*.psd" --everything, que reescreve o histórico de volta. Depois é preciso remover as regras do .gitattributes e fazer force push.

O git diff funciona com arquivos no LFS?

O Git mostra a alteração do ponteiro, e não do conteúdo, porque os arquivos são binários. Para imagens e documentos, a comparação é feita com ferramentas externas.

Todos no time precisam do LFS?

Sim; caso contrário, quem não tiver a extensão verá ponteiros no lugar dos arquivos na cópia de trabalho, e os commits dessa pessoa podem adicionar arquivos grandes por fora do LFS sem querer.

Aprenda este tema em vídeo

Este tema é abordado em profundidade, com prática, no curso “Git do zero ao desenvolvedor confiante”.

Ir para o curso