Gerenciar e armazenar arquivos grandes no Git

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

O Git ajuda a manter pequeno o volume do código-fonte, pois as diferenças entre as versões são facilmente selecionadas e o código é facilmente compactado. Os arquivos grandes que não são bem compactados e mudam inteiramente entre as versões (como os binários) apresentam problemas quando armazenados em seus repositórios Git. O desempenho rápido do Git vem de sua capacidade de atender e alternar para todas as versões de um arquivo a partir de seu armazenamento local.

Se tiver arquivos grandes e impossíveis de serem comparados em seu repositório, como por exemplo binários, você manterá uma cópia completa desse arquivo em seu repositório sempre que confirmar uma alteração no arquivo. Se houver muitas versões desses arquivos em seu repositório, elas aumentarão drasticamente o tempo de check-out, ramificação, busca e clonagem do código.

Que tipo de arquivos você deve armazenar no Git?

Confirme o código-fonte, não as dependências

Como sua equipe trabalha com editores e ferramentas para criar e atualizar arquivos, você deve colocar esses arquivos no Git para que sua equipe possa aproveitar os benefícios do fluxo de trabalho do Git. Não envie outros tipos de arquivos em seu repositório: por exemplo, DLLs, arquivos de biblioteca e outras dependências que sua equipe não cria, mas das quais seu código depende. Entregue esses arquivos por meio do gerenciamento de pacotes a seus sistemas.

O gerenciamento de pacotes agrupa suas dependências e instala os arquivos em seu sistema quando você implanta o pacote. Os pacotes são versionados para garantir que o código testado em um ambiente seja executado da mesma forma que em outros ambientes, desde que tenham os mesmos pacotes instalados.

Não faça commit das saídas

Não faça commit dos binários, logs, resultados de rastreamento ou dados de diagnóstico de seus builds e testes. Esses itens são produtos de seu código, não o próprio código-fonte. Compartilhe logs e informações de rastreamento com sua equipe por meio de ferramentas de acompanhamento de itens de trabalho ou por meio do compartilhamento de arquivos da equipe.

Armazenar fontes binárias pequenas e raramente atualizadas no Git

Os arquivos de origem binários que são atualizados com pouca frequência têm relativamente poucas versões confirmadas. Eles não ocupam muito espaço se o tamanho do arquivo for pequeno. Imagens para a Web, ícones e outros ativos de gráficos menores podem se enquadrar nessa categoria. É melhor armazenar esses arquivos no Git com o restante do seu código-fonte para que sua equipe possa usar um fluxo de trabalho consistente.

Importante

Mesmo binários pequenos podem causar problemas se atualizados com frequência. Por exemplo, 100 alterações em um arquivo binário de 100 KB usam tanto armazenamento quanto 10 alterações em um binário de 1 MB. Devido à frequência de atualizações, o binário menor diminuirá o desempenho da ramificação com mais frequência do que o binário grande.

Não faça commit de ativos binários grandes e frequentemente atualizados

O Git gerencia uma versão principal de um arquivo e armazena apenas as diferenças dessa versão, em um processo conhecido como deltificação. A deltificação e a compactação de arquivos permitem que o Git armazene seu histórico de código inteiro no repositório local. Binários grandes geralmente mudam totalmente entre as versões e muitas vezes já estão compactados. Esses arquivos são difíceis para o Git gerenciar porque as diferenças entre as versões são grandes.

O Git deve armazenar todo o conteúdo de cada versão do arquivo e tem dificuldade em economizar espaço por meio da deltificação e da compactação. Armazenar as versões completas desses arquivos faz com que o tamanho do repositório aumente com o tempo. O aumento do tamanho do repositório reduz o desempenho da ramificação, aumenta os tempos de clone e expande os requisitos de armazenamento.

Estratégias para trabalhar com arquivos de origem binários grandes

  • Não faça commit de arquivos compactados de dados. É melhor descompactar os arquivos e confirmar as fontes difusíveis. Deixe o Git lidar com a compactação dos dados em seu repositório.
  • Evite confirmar código compilado e outras dependências binárias. Faça o commit do código-fonte e crie as dependências, ou use uma solução de gerenciamento de pacotes para versionamento e forneça esses arquivos ao sistema.
  • Armazene a configuração e outros dados estruturados em formatos de texto sem formatação em que é possível fazer diff, como por exemplo JSON.

O que é Git LFS?

Quando você tiver arquivos de origem com grandes diferenças entre as versões e atualizações frequentes, poderá usar o Git Large File Storage (LFS) para gerenciar esses tipos de arquivos. O Git LFS é uma extensão do Git que fornece dados que descrevem os arquivos grandes em um commit para o seu repositório. Ele armazena o conteúdo do arquivo binário em armazenamento remoto separado.

Quando você clona e alterna branches no repositório, o Git LFS baixa a versão correta desse armazenamento remoto. As ferramentas de desenvolvimento local trabalharão de forma transparente com os arquivos como se tivessem sido confirmados diretamente no repositório.

Benefícios

O benefício do Git LFS é que sua equipe pode usar o fluxo de trabalho do Git de ponta a ponta familiar, independentemente dos arquivos que a equipe cria. O LFS lida com arquivos grandes para evitar que afetem negativamente o repositório geral. Além disso, a partir da versão 2.0, o Git LFS dá suporte ao bloqueio de arquivos para ajudar sua equipe a trabalhar em ativos grandes e indistinguíveis, como vídeos, sons e mapas de jogos.

O Git LFS é totalmente compatível e gratuito no Azure DevOps Services. Para usar o LFS com o Visual Studio, você precisa pelo menos do Visual Studio 2015 Atualização 2 ou superior. Basta seguir as instruções para instalar o cliente, configurar o rastreamento LFS para arquivos em seu repositório local e, em seguida, enviar suas alterações por push para o Azure Repos.

Limitações

O Git LFS tem algumas desvantagens que devem ser consideradas considerar antes de adotar:

  • Cada cliente Git usado por sua equipe deve instalar o cliente Git LFS e entender sua configuração de acompanhamento.
  • Se o cliente Git LFS não estiver instalado e configurado corretamente, você não verá os arquivos binários confirmados por meio do Git LFS ao clonar seu repositório. O Git baixará os dados que descrevem o arquivo grande (que é o que o Git LFS confirma no repositório) e não o arquivo binário real em si. A confirmação de binários grandes sem o cliente Git LFS instalado enviará o binário por push para o repositório.
  • O Git não pode mesclar as alterações de duas versões diferentes de um arquivo binário, mesmo que ambas as versões tenham um pai comum. Se duas pessoas estiverem trabalhando no mesmo arquivo ao mesmo tempo, elas deverão trabalhar juntas para reconciliar as alterações e evitar substituir o trabalho do outro. O Git LFS fornece bloqueio de arquivo para ajudar. Os usuários ainda devem ter o cuidado de sempre extrair a cópia mais recente de um ativo binário antes de iniciar o trabalho.
  • O Azure Repos atualmente não dá suporte ao uso de Secure Shell (SSH) em repositórios com arquivos rastreados pelo Git LFS.
  • Se um usuário arrastar e soltar um arquivo binário por meio da interface da Web em um repositório configurado para o Git LFS, o binário será confirmado no repositório e não nos ponteiros que seriam confirmados por meio do cliente Git LFS.
  • Embora não haja uma restrição estrita de tamanho de arquivo, o espaço livre disponível do servidor e a carga de trabalho atual podem restringir o desempenho e a funcionalidade.
  • O limite de tempo para upload de um arquivo é de uma hora.

Formato de arquivo

O arquivo gravado no repositório para um arquivo controlado pelo Git LFS terá algumas linhas com um par de chave e valor em cada linha:

version https://git-lfs.github.com/spec/v1
oid a747cfbbef63fc0a3f5ffca332ae486ee7bf77c1d1b9b2de02e261ef97d085fe
size 4923023

Observação

A URL do GitHub incluída para o valor de versão define apenas o tipo de arquivo de ponteiro LFS. Não é um link para seu arquivo binário.

Problemas conhecidos

Se você usar uma versão do LFS anterior à 2.4.0 com Azure DevOps Server, será necessária uma etapa de configuração extra para autenticar via NTLM em vez de Kerberos. Essa etapa não é mais necessária a partir do LFS 2.4.0 e a atualização é altamente recomendável.