Estou procurando opiniões sobre como lidar com arquivos binários grandes dos quais meu código-fonte (aplicativo Web) depende. No momento, estamos discutindo várias alternativas:
- Copie os arquivos binários manualmente.
- Pro: Não tenho certeza.
- Contra: Sou totalmente contra isso, pois aumenta a probabilidade de erros ao configurar um novo site / migrar o antigo. Constrói outro obstáculo a ser enfrentado.
- Gerencie todos eles com o Git .
- Pro: remove a possibilidade de 'esquecer' de copiar um arquivo importante
- Contra: Incha o repositório e diminui a flexibilidade para gerenciar a base de código e checkouts, clones etc. levarão um bom tempo.
- Repositórios separados.
- Pro: O check-out / clonagem do código-fonte está mais rápido do que nunca e as imagens são arquivadas corretamente em seu próprio repositório.
- Contra: remove a simplicidade de ter o único repositório Git no projeto. Certamente introduz algumas outras coisas em que não pensei.
Quais são suas experiências / pensamentos sobre isso?
Além disso: alguém tem experiência com vários repositórios Git e com o gerenciamento deles em um projeto?
Os arquivos são imagens para um programa que gera PDFs com esses arquivos. Os arquivos não mudam com muita frequência (como em anos), mas são muito relevantes para um programa. O programa não funcionará sem os arquivos.
Respostas:
Se o programa não funcionar sem os arquivos, parece que dividi-los em um repositório separado é uma má idéia. Temos grandes suítes de teste que dividimos em um repositório separado, mas esses são arquivos verdadeiramente "auxiliares".
No entanto, você pode gerenciar os arquivos em um repositório separado e usá
git-submodule
-los para atraí-los para o seu projeto de maneira sã. Então, você ainda teria o histórico completo de toda a sua fonte, mas, pelo que entendi, você teria apenas uma revisão relevante do submódulo de suas imagens. Ogit-submodule
recurso deve ajudá-lo a manter a versão correta do código alinhada com a versão correta das imagens.Aqui está uma boa introdução aos submódulos do Git Book.
fonte
Descobri recentemente o git-anexo, que acho incrível. Foi projetado para gerenciar arquivos grandes com eficiência. Eu o uso para minhas coleções de fotos / músicas (etc.). O desenvolvimento do git-anexo é muito ativo. O conteúdo dos arquivos pode ser removido do repositório Git, apenas a hierarquia da árvore é rastreada pelo Git (por meio de links simbólicos). No entanto, para obter o conteúdo do arquivo, é necessário um segundo passo após puxar / empurrar, por exemplo:
Existem muitos comandos disponíveis e há uma excelente documentação no site. Um pacote está disponível no Debian .
fonte
git annex
está disponível no Windows . Se alguém já o testou no Windows, gostaria de saber sobre sua experiência!Outra solução, desde abril de 2015, é o LFS (Git Large File Storage) (do GitHub).
Ele usa git-lfs (consulte git-lfs.github.com ) e é testado com um servidor que o suporta: lfs-test-server :
você pode armazenar metadados somente no repositório git e no arquivo grande em outro lugar.
fonte
lfs-test-server
é declarado não para uso em produção. Na verdade, estou trabalhando no servidor LFS de produção ( github.com/artemkin/git-lfs-server ). Está em andamento, mas já pode ser reparado, e estamos testando-o internamente.Dê uma olhada no git bup que é uma extensão do Git para armazenar binários grandes de maneira inteligente em um repositório do Git.
Você gostaria de tê-lo como um submódulo, mas não precisará se preocupar com o repositório ficando difícil de manusear. Um de seus casos de uso de amostra é armazenar imagens de VM no Git.
Na verdade, não vi melhores taxas de compactação, mas meus repositórios não possuem binários realmente grandes.
Sua milhagem pode variar.
fonte
Você também pode usar git-fat . Eu gosto que só depende de estoque Python e
rsync
. Ele também suporta o fluxo de trabalho Git usual, com os seguintes comandos auto-explicativos:Além disso, você precisa fazer o check-in de um arquivo .gitfat no seu repositório e modificar seus atributos .gitatat para especificar as extensões de arquivo que deseja
git fat
gerenciar.Você adiciona um binário usando o normal
git add
, que por sua vez chama comgit fat
base em suas regras de gitattributes.Por fim, tem a vantagem de que o local onde seus binários estão realmente armazenados pode ser compartilhado entre repositórios e usuários e suporta qualquer coisa
rsync
faz.ATUALIZAÇÃO: Não use git-fat se estiver usando uma ponte Git-SVN. Isso acabará removendo os arquivos binários do seu repositório Subversion. No entanto, se você estiver usando um repositório Git puro, ele funcionará perfeitamente.
fonte
Eu usaria submódulos (como Pat Notz) ou dois repositórios distintos. Se você modificar seus arquivos binários com muita frequência, tentarei minimizar o impacto do enorme repositório que limpa o histórico:
Eu tive um problema muito parecido há vários meses: ~ 21 GB de arquivos MP3, não classificados (nomes ruins, id3s ruins, não sei se eu gosto ou não desse arquivo MP3 ...) e replicados em três computadores.
Usei uma unidade de disco rígido externa com o repositório principal do Git e a clonei em cada computador. Então, comecei a classificá-los da maneira habitual (empurrando, puxando, mesclando ... excluindo e renomeando muitas vezes).
No final, eu tinha apenas ~ 6 GB de arquivos MP3 e ~ 83 GB no diretório .git. Eu usei
git-write-tree
egit-commit-tree
criei um novo commit, sem ancestrais de commit, e iniciei um novo ramo apontando para esse commit. O "log git" para esse ramo mostrou apenas uma confirmação.Em seguida, excluí o ramo antigo, mantive apenas o novo ramo, excluí os ref-logs e execute "git prune": depois disso, minhas pastas .git pesavam apenas ~ 6 GB ...
Você pode "limpar" o enorme repositório de tempos em tempos da mesma maneira: seu "git clone" será mais rápido.
fonte
A solução que eu gostaria de propor é baseada em filiais órfãs e um leve abuso do mecanismo de tags, doravante referido como * Armazenamento Binário de Tags Órfãs (OTABS)
TL; DR 12-01-2017 Se você pode usar o LFS do github ou algum outro fabricante, por todos os meios, deve. Se não puder, continue a ler. Esteja avisado, esta solução é um hack e deve ser tratada como tal.
Propriedades desejáveis do OTABS
git pull
egit fetch
, incluindogit fetch --all
ainda são eficientes na largura de banda , ou seja, nem todos os binários grandes são extraídos do controle remoto por padrão.Propriedades indesejáveis do OTABS
git clone
potencialmente ineficiente (mas não necessariamente, dependendo do seu uso). Se você implantar esta solução, poderá ter que aconselhar seus colegas a usar emgit clone -b master --single-branch <url>
vez degit clone
. Isso ocorre porque o git clone, por padrão, literalmente clona todo o repositório, incluindo coisas nas quais você normalmente não gostaria de desperdiçar sua largura de banda, como confirmações não referenciadas. Retirado de SO 4811434 .git fetch <remote> --tags
largura de banda ineficiente, mas não necessariamente ineficiente de armazenamento. Você sempre pode aconselhar seus colegas a não usá-lo.git gc
truque para limpar seu repositório de qualquer arquivo que não desejar mais.Adicionando os arquivos binários
Antes de começar, verifique se você confirmou todas as alterações, sua árvore de trabalho está atualizada e seu índice não contém alterações não confirmadas. Pode ser uma boa ideia enviar todas as suas ramificações locais para o controle remoto (github etc.), caso ocorra algum desastre.
git checkout --orphan binaryStuff
fará o truque. Isso produz uma ramificação totalmente desconectada de qualquer outra ramificação, e o primeiro commit que você fará neste branch não terá pai, o que o tornará um commit raiz.git rm --cached * .gitignore
.rm -fr * .gitignore
. O.git
diretório interno permanecerá intocado, porque o*
curinga não corresponde a ele.git fetch
entupimento de sua conexão. Você pode evitar isso pressionando uma tag em vez de um ramo. Isso ainda pode afetar a largura de banda e o armazenamento do sistema de arquivos do seu colega se ele tiver o hábito de digitargit fetch <remote> --tags
, mas continue lendo para obter uma solução alternativa. Vá em frente egit tag 1.0.0bin
git push <remote> 1.0.0bin
.git branch -D binaryStuff
. Seu commit não será marcado para coleta de lixo, porque uma tag órfã apontando nele1.0.0bin
é suficiente para mantê-lo ativo.Verificando o arquivo binário
git checkout 1.0.0bin -- VeryBigBinary.exe
.1.0.0bin
baixado a tag órfã ; nesse caso, você precisará fazê-lo comgit fetch <remote> 1.0.0bin
antecedência.VeryBigBinary.exe
ao seu mestrado.gitignore
, para que ninguém em sua equipe polua o histórico principal do projeto com o binário por acidente.Excluindo completamente o arquivo binário
Se você decidir limpar completamente o VeryBigBinary.exe do repositório local, do repositório remoto e dos repositórios de seus colegas, você pode:
git push <remote> :refs/tags/1.0.0bin
git tag -l | xargs git tag -d && git fetch --tags
. Retirado de SO 1841341 com ligeira modificação.git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"
. Ele também excluirá todas as outras confirmações não referenciadas. Retirado de SO 1904860git clone -b master --single-branch <url>
vez degit clone
.2.0.0bin
. Se você está preocupado com a digitação de seus colegas,git fetch <remote> --tags
pode realmente nomeá-lo novamente1.0.0bin
. Isso garantirá que, da próxima vez que buscarem todas as tags, as antigas1.0.0bin
não sejam referenciadas e marcadas para a coleta de lixo subsequente (usando a etapa 3). Ao tentar sobrescrever uma tag no controle remoto, você deve usar-f
assim:git push -f <remote> <tagname>
Posfácio
O OTABS não toca em seu mestre nem em nenhum outro ramo de código-fonte / desenvolvimento. Os hashes de consolidação, todo o histórico e o tamanho pequeno dessas ramificações não são afetados. Se você já inchado seu histórico de código-fonte com arquivos binários, será necessário limpá-lo como um trabalho separado. Este script pode ser útil.
Confirmado para funcionar no Windows com git-bash.
É uma boa idéia aplicar um conjunto de trics padrão para tornar o armazenamento de arquivos binários mais eficiente. A execução frequente
git gc
(sem argumentos adicionais) faz com que o git otimize o armazenamento subjacente de seus arquivos usando deltas binários. No entanto, se é improvável que seus arquivos permaneçam similares de commit para commit, você pode desativar completamente os deltas binários. Além disso, como não faz sentido compactar arquivos já compactados ou criptografados, como .zip, .jpg ou .crypt, o git permite desativar a compactação do armazenamento subjacente. Infelizmente, é uma configuração de tudo ou nada que afeta o seu código-fonte também.Você pode criar scripts de partes do OTABS para permitir um uso mais rápido. Em particular, as etapas de script 2-3 de Excluir completamente arquivos binários em um
update
gancho git podem fornecer uma semântica atraente, mas talvez perigosa, para o git fetch ("buscar e excluir tudo o que estiver desatualizado").Você pode pular a etapa 4 de Exclusão completa de arquivos binários para manter um histórico completo de todas as alterações binárias no controle remoto, ao custo do inchaço do repositório central. Repositórios locais permanecerão enxutos com o tempo.
No mundo Java, é possível combinar essa solução
maven --offline
para criar uma compilação offline reproduzível, armazenada inteiramente em seu controle de versão (é mais fácil com o maven do que com o gradle). No mundo Golang, é possível desenvolver essa solução para gerenciar seu GOPATH em vez dego get
. No mundo python, é possível combinar isso com o virtualenv para produzir um ambiente de desenvolvimento independente, sem depender dos servidores PyPi para todas as compilações do zero.Se os seus arquivos binários mudar muito frequentemente, como artefatos de construção, pode ser uma boa idéia para o script uma solução que armazena 5 versões mais recentes dos artefatos nas tags órfãs
monday_bin
,tuesday_bin
, ...,friday_bin
, e também uma tag órfão para cada versão1.7.8bin
2.0.0bin
, etc. Você pode girarweekday_bin
e excluir binários antigos diariamente. Dessa forma, você obtém o melhor de dois mundos: mantém todo o histórico do seu código-fonte, mas apenas o histórico relevante das suas dependências binárias. Também é muito fácil obter os arquivos binários de uma determinada tag sem obter todo o código-fonte com todo o seu histórico:git init && git remote add <name> <url> && git fetch <name> <tag>
faça isso por você.fonte
git gc
" - parou de ler ali. Por que alguém desistiria do seu último cinto de segurança em favor de algum truque?git gc
não é seguro para executar. Todos os seus commits pendentes será seguramente manter no disco rígido por pelo menos 30 dias por padrão: git-scm.com/docs/git-gcgit push <remote> 1.0.0bin
-remote: error: GH001: Large files detected. You may want to try Git Large File Storage
. Parece que talvez o GitHub não esteja mais apoiando isso? O binário em questão tinha 100 MB de tamanho.Na minha opinião, se é provável que você modifique esses arquivos grandes com frequência, ou se pretende criar muitos
git clone
ougit checkout
, considere seriamente usar outro repositório Git (ou talvez outra maneira de acessar esses arquivos).Mas se você trabalha como nós, e se seus arquivos binários não são modificados com frequência, o primeiro clone / checkout será longo, mas depois disso deve ser o mais rápido que você deseja (considerando que seus usuários continuam usando o primeiro repositório clonado que eles teve).
fonte
O SVN parece lidar com deltas binários com mais eficiência que o Git.
Eu tive que decidir sobre um sistema de controle de versão para documentação (arquivos JPEG, arquivos PDF e arquivos .odt). Acabei de testar adicionando um arquivo JPEG e girando-o 90 graus quatro vezes (para verificar a eficácia dos deltas binários). O repositório do Git cresceu 400%. O repositório do SVN cresceu apenas 11%.
Portanto, parece que o SVN é muito mais eficiente com arquivos binários.
Então, minha escolha é Git para código fonte e SVN para arquivos binários, como documentação.
fonte
git gc
o tamanho total do repositório git, foi reduzido para 184 KB. Em seguida, alterei um único pixel de branco para preto e confirmei essa alteração, o tamanho total do repositório git aumentou para 388KB e depois quegit gc
o tamanho do repositório total git foi reduzido para 184KB. Isso mostra que o git é muito bom em compactar e encontrar deltas de arquivos binários.git clone --filter
do Git 2.19 + clones rasosEssa nova opção pode eventualmente se tornar a solução final para o problema do arquivo binário, se o Git e o GitHub os desenvolverem e o tornarem bastante amigável (o que eles provavelmente ainda não alcançaram em sub - módulos, por exemplo).
Na verdade, ele permite buscar apenas arquivos e diretórios que você deseja para o servidor e foi apresentado juntamente com uma extensão de protocolo remoto.
Com isso, podemos primeiro fazer um clone superficial e depois automatizar quais blobs buscar no sistema de compilação para cada tipo de compilação.
Já existe um
--filter=blob:limit<size>
que permite limitar o tamanho máximo de blob para buscar.Forneci um exemplo mínimo e detalhado de como o recurso se parece: Como clonar um subdiretório apenas de um repositório Git?
fonte
Eu, pessoalmente, deparei com falhas de sincronização com o Git com alguns dos meus hosts na nuvem, uma vez que os dados binários dos meus aplicativos da Web ultrapassam a marca de 3 GB . Eu considerava o BFT Repo Cleaner na época, mas parecia um hack. Desde então, comecei a manter os arquivos fora do alcance do Git, aproveitando as ferramentas criadas especificamente para fins específicos , como o Amazon S3, para gerenciar arquivos, controle de versão e backup.
Sim. Os temas de Hugo são gerenciados principalmente dessa maneira. É um pouco bizarro, mas faz o trabalho.
Minha sugestão é escolher a ferramenta certa para o trabalho . Se for para uma empresa e você estiver gerenciando sua linha de código no GitHub, pague o dinheiro e use o Git-LFS. Caso contrário, você poderá explorar opções mais criativas, como armazenamento de arquivos criptografado e descentralizado usando blockchain .
Opções adicionais a serem consideradas incluem Minio e s3cmd .
fonte
Dê uma olhada no camlistore . Não é realmente baseado em Git, mas acho mais apropriado para o que você precisa fazer.
fonte