Lidando com arquivos grandes no Git com Git LFS

Git Lfs  (Git Large File Storage) é uma extensão para o Git que permite ao famoso sistema de controle de versão a lidar com arquivos grandes. Em regras gerais um sistema como Git não é adequado a gerenciar arquivos binários principalmente se forem da ordem dos Megabytes, daí a necessidade do Git Lfs.

Adicionando um arquivo grande (da forma errada)

Se você adicionar o seu arquivo binário no Git, simplesmente vai funcionar.

git add meuarquivogrande.iso
git commit -am 'Adicionando indevidamente um arquivo gigante'

O problema é que se você alterar este arquivo e adicioná-lo novamente e novamente e depois outra vez, em pouco tempo você precisar um disco imenso para guardar todas as versões deste arquivo.

Ignorando arquivos

Uma alternativa (para alguns casos) seria adicionar uma regra no seu .gitignore para que o Git faça vista grossa a estes arquivos.

echo '*.iso' >>.gitignore

O problema disso é que se você realmente precisar do arquivo em outras máquinas onde trabalhar com este repositório, pode haver necessidade do arquivo estar presente. É ai que entra o “Git lfs”.

Instalando o Git lfs

O Git Lfs é um “plugin” para o Git que trabalh com o gancho “pre-commit” monitorando tudo o que é submetido e se o arquivo enviado estiver dentro de suas regras ele intercepta o arquivo e dá uma melhor tratativa.

Para instá-lo o processo é bem simples e rápido. Primeiro instale o pacote do Git Lfs com os comandos abaixo:

sudo apt install curl
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs

Veja que o primeiro comando é apenas para instalar o “curl”, quem fará o download do pacote do Git Lfs de fato, portanto se você já tiver o curl instalado ou optar por fazer o download manualmente esta linha é opcional.

Da mesma forma a segunda linha. Que baixa um script “.sh” e o submete ao bash para executá-lo. Este script configura o seu sources.list para realizar o donwload e instalação do gitlfs via apt, mas você pode opcionalmente baixar apenas o arquivo .deb no site do projeto git-lfs

A terceira linha finalmente instala o git lfs no seu sistema, mas observe que isso não habilita o seu repositório a usá-lo ainda, o que requer mais alguns passos.

Habilitando o Git lfs

Com o git lfs instalado vamos habilitá-lo globalmente com o comando abaixo:

git lfs install

Agora dentro o seu repositório você só precisa adicionar as regras de filtragem do LFS.

git lfs track '*.iso'
git lfs track '*.zip'

A partir daí todos os seu arquivos iso e zip serão gerenciados pelo git lfs e não ocuparão espaço exagerado indevidamente. Caso você já tenha versionado arquivos grandes no seu repositório infelizmente não há um jeito fácil de se desfazer isso. Há inúmeros tutoriais por ai explicando maneiras de se fazê-lo mas nenhuma que seja muito fácil.

Para ver os arquivos gerenciados pelo Git lfs você pode usar o comando “ls-files”.

git lfs ls-files

Consulte a documentação para maiores detalhes, mas basicamente é isso.

Fiz tudo direito mas não funcionou

[update 13-04-2017]

Pessoal, uma coisa faltou comentar é que há necessidade de um servidor Git adequado para que o Git LFS funcione a contento. O procedimento que descrevi é para configuração do cliente, não do servidor remoto onde você fará os seus “git push/pull”.

Depois que você fizer o procedimento descrito no texto e der um git push para o seu servidor, se receber uma mensagem como a mostrada abaixo é porque seu servidor não está configurado para este recurso (sorry!)

$ git push
Git LFS: (0 of 1 files) 0 B / 79.44 MB                                         
batch request: exit status 127: bash: git-lfs-authenticate: comando não encontrado
error: failed to push some refs to 'wbraga@localhost:/tmp/tg.git'

Fica para uma próximo texto como configurar um servidor Git remoto com suporte ao Git LFS

2 ideias sobre “Lidando com arquivos grandes no Git com Git LFS”

  1. Olá,

    Estou com problemas quando tento utilizar o git lfs. Acontece isto:

    xx@xxxxx:~/Documents/sandbox/test_lfs$ git push origin master
    git@123.154.1.7’s password: git@123.154.1.7’s password:
    git@123.154.1.7s password:
    Git LFS: (0 of 1 files) 0 B / 1.71 GB
    batch request: bash: git-lfs-authenticate: command not found: exit status 127
    error: failed to push some refs to ‘git@123.154.1.7:/media/test_lfs.git’

    O que poderá ser?
    Como faço para que todos os arquivos sejam geridos pelo lfs? Pois neste caso não é um ficheiro apenas que é grande, mas sim vários que acabam por fazer o repositório enorme >8GB

    1. Olá Eder,

      Qual é o seu servidor Git (apenas o Git puro instalado, Github, Bitbucket, Gitlab …) ?

      Meus servidores Git principais são o Bitbucket para projetos pessoais e GitLab para o trabalho profissional onde o Git LFS tem funcionado sem problemas apenas com o passo a passo descrito no texto, no entanto fiz uma simulação criando um repositório local bem basico e seguindo o texto escrito, que sempre funcionou, cheguei ao mesmo erro que você.

      Procurando uma resposta para o problema me deparei com várias páginas falando sobre uma limitação do Git LFS que é a autenticação só funcionar em modo HTTP/HTTPS, ou seja usar SSH para o Git LFS não funciona. Por isso que nunca tive problemas, já que meus servidores Git provem ambas as formas de acesso.

      Até existe uma ferramenta para autenticação chamada git-lfs-authenticate, que ainda não parei para verificar como ela funciona exatamente mas, pela leitura superficial que fiz, parece que ainda assim o LFS só transferirá arquivos via HTTP.

      Como o texto apenas aborda a configuração do cliente Git, atualizei apenas informando que é necessário um servidor Git compatível. Em um futuro post, após pesquisar melhor sobre o assunto, eu publico como criar um servidor Git com suporte ao LFS.

      Algumas das eferências sobre o fato são:
      [1] Git LFS – Autentication – https://github.com/git-lfs/git-lfs/blob/master/docs/api/authentication.md
      [2] Git LFS – Issue 1044 – https://github.com/git-lfs/git-lfs/issues/1044
      [3] Git LFS – Issue 1089 – https://github.com/git-lfs/git-lfs/issues/1089
      [4] Gitlab CE – Issue 3589 – https://gitlab.com/gitlab-org/gitlab-ce/issues/3589

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *