Pergunta

Eu estou procurando opiniões de como lidar com grandes arquivos binários em que o meu código fonte (aplicação web) é dependente. Atualmente estamos discutindo várias alternativas:

  1. Copie os arquivos binários com a mão.
    • Pro:. Não tenho certeza
    • Contra: Eu sou fortemente contra isso, pois aumenta a probabilidade de erros quando a criação de um novo site / migrar do antigo. Constrói-se um outro obstáculo a tomar.
  2. Gerenciar todos eles com Git .
    • Pro: Remove a possibilidade de 'esquecer' para copiar um arquivo importante
    • Contra:. Bloats o repositório e diminui a flexibilidade para gerenciar o código-base e checkouts, clones, etc. vai demorar um pouco
  3. repositórios separados.
    • Pro:. O check-out / clonagem do código-fonte é rápido como sempre, e as imagens são devidamente arquivados em seu próprio repositório
    • Contra: Remove a simplicidade de ter o único repositório Git no projeto. Ele certamente introduz algumas outras coisas que eu não tenha pensado.

Quais são suas experiências / pensamentos sobre isso?

Além disso:? Alguém tem experiência com múltiplos repositórios Git e gerenciá-los em um projeto

Os arquivos são imagens para um programa que gera PDFs com esses arquivos nele. Os arquivos não vai mudar muito frequentemente (como em anos), mas eles são muito relevantes para um programa. O programa não funcionará sem os arquivos.

Foi útil?

Solução

Se o programa não funcionará sem os arquivos parece que dividi-los em um repositório separado é uma má idéia. Temos suites de teste grandes que quebram em um repositório separado, mas aqueles que são verdadeiramente arquivos "auxiliares".

No entanto, você pode ser capaz de gerenciar os arquivos em um repositório separado e, em seguida, usar git-submodule para puxá-los em seu projeto de uma forma sã. Então, você ainda tem a história completa de toda a sua fonte, mas, como eu o entendo, você só teria a revisão relevante do seu imagens submodule. A instalação git-submodule deve ajudá-lo a manter a versão correta do código de acordo com a versão correta das imagens.

Aqui está uma boa introdução à submódulos de Git Book.

Outras dicas

git-anexo recentemente que eu acho incrível. Ele foi projetado para o gerenciamento de arquivos grandes de forma eficiente. Eu uso ele para a minha foto / música (etc.) coleções. O desenvolvimento de git-anexo é muito ativa. O conteúdo dos arquivos pode ser removido a partir do repositório Git, somente a hierarquia de árvore é rastreado por Git (através de links simbólicos). No entanto, para obter o conteúdo do arquivo, uma segunda etapa é necessária depois de puxar / empurrar, por exemplo:.

$ git annex add mybigfile
$ git commit -m'add mybigfile'
$ git push myremote
$ git annex copy --to myremote mybigfile ## This command copies the actual content to myremote
$ git annex drop mybigfile ## Remove content from local repo
...
$ git annex get mybigfile ## Retrieve the content
## or to specify the remote from which to get:
$ git annex copy --from myremote mybigfile

Existem muitos comandos disponíveis, e há uma grande documentação no site. Um pacote está disponível em Debian .

Outra solução, desde abril de 2015 é Git Grande Storage File (LFS) (por GitHub).

Ele usa git-LFS (veja < a href = "https://git-lfs.github.com/" rel = "noreferrer"> git-lfs.github.com ) e testado com um servidor de suporte que: LFS-test-server :
Você pode armazenar metadados apenas no repo git, eo grande arquivo em outro lugar.

https://cloud.githubusercontent.com/assets/1319791/7051226/c4570828-ddf4-11e4-87eb -8fc165e5ece4.gif

Tenha um olhar em git bup que é uma extensão Git para armazenar de forma inteligente grandes binários em um Git repositório.

Você gostaria de tê-lo como um sub-módulo, mas você não terá que se preocupar com o repositório ficando difícil de manusear. Um de seus casos de uso de amostra está armazenando imagens de VM em Git.

Eu não tenho realmente visto melhores taxas de compressão, mas meus repositórios não tem realmente grandes binários em si.

Sua milhagem pode variar.

Você também pode usar git-fat . Eu gosto que ele só depende de estoque Python e rsync . Ele também suporta o fluxo de trabalho habitual Git, com os seguintes comandos auto-explicativos:

git fat init
git fat push
git fat pull

Além disso, é preciso verificar em um arquivo .gitfat em seu repositório e modificar suas .gitattributes para especificar as extensões de arquivo que você quer git fat de gerir.

Você adiciona um binário usando o git add normal, que por sua vez invoca git fat com base em suas regras gitattributes.

Finalmente, ele tem a vantagem de que o local onde os binários são realmente armazenados podem ser compartilhados entre repositórios e usuários e suportes nada rsync faz.

UPDATE: não usar git-gordura, se você estiver usando uma ponte Git-SVN. Ele vai acabar a remoção dos arquivos binários de seu repositório Subversion. No entanto, se você estiver usando um repositório Git pura, ele funciona muito bem.

Gostaria de usar sub-módulos (como Pat Notz) ou dois repositórios distintos. Se você modificar seus arquivos binários, muitas vezes, então eu iria tentar minimizar o impacto da enorme repositório de limpeza da história:

Eu tive um problema muito semelhante há vários meses: ~ 21 GB de arquivos MP3, não classificados (nomes mau, mau id3 de, não sei se eu como aquele arquivo MP3 ou não ...), e replicado em três computadores .

Eu usei um disco rígido externo com o principal repositório Git, e eu clonado lo em cada computador. Então, comecei a classificá-los da maneira habitual (empurrar, puxar, fundindo ... apagar e renomear muitas vezes).

No final, eu tinha apenas ~ 6 GB de arquivos MP3 e ~ 83 GB no diretório .git. Eu costumava git-write-tree e git-commit-tree para criar um novo commit, sem comprometer antepassados, e começou uma nova apontando galho em que cometeu. O "git log" para esse ramo só mostrou um commit.

Então, eu deletei o velho ramo, mantido apenas o novo ramo, eliminado o árbitro-logs, e executar "git ameixa seca": depois disso, minhas pastas .git ponderada apenas ~ 6 GB ...

Você poderia "purga" a enorme repositório de vez em quando, da mesma forma:. O seu "clone git" 's será mais rápido

Na minha opinião, se você é provável que muitas vezes modificar esses arquivos grandes, ou se você pretende fazer um monte de git clone ou git checkout, então você deve considerar seriamente o uso de outro repositório Git (ou talvez uma outra maneira de acessar esses arquivos ).

Mas se você trabalhar como nós fazemos, e se seus arquivos binários não são muitas vezes modificados, em seguida, o primeiro clone / checkout será longa, mas depois que ele deve ser tão rápido quanto você quiser (considerando seus usuários continuar usando o primeiro repositório clonado eles tinham).

A solução que eu gostaria de propor baseia-se em ramos órfãos e uma ligeira abuso do mecanismo de tag, doravante referidos como * Orphan Etiquetas binário armazenamento (OTABS)

TL; DR 2017/12/01 Se você pode usar LFS do github ou algum outro 3rd party, por todos os meios que você deve. Se não for possível, então continue a ler. Esteja avisado, esta solução é um hack e deve ser tratado como tal.

propriedades desejáveis ??de OTABS

  • é um pura git e git única solução - que começa o trabalho feito sem qualquer software 3o partido (como git-anexo) ou infra-estrutura do 3o partido (como LFS do github).
  • que armazena os arquivos binários eficientemente , ou seja, ele não inchar a história de seu repositório.
  • git pull e git fetch, incluindo git fetch --all ainda são largura de banda eficiente , ou seja, nem todos os grandes binários são puxados a partir do controle remoto por padrão.
  • ele funciona em Windows .
  • ele armazena tudo em um único git repositório .
  • que permite exclusão de binários desatualizados (ao contrário bup).

propriedades indesejáveis ??de OTABS

  • torna git clone potencialmente ineficiente (mas não necessariamente, dependendo do seu uso). Se você implantar essa solução você pode ter que aconselhar os seus colegas para uso git clone -b master --single-branch <url> vez de git clone. Isso ocorre porque clone git por padrão literalmente clones toda repositório, incluindo coisas que você normalmente não querem perder a sua largura de banda, como commits sem referência. Tomado de SO 4.811.434 .
  • torna largura de banda git fetch <remote> --tags ineficiente, mas não necessariamente de armazenamento ineficiente. Você pode sempre pode aconselhar os seus colegas não usá-lo.
  • você vai ter que usar periodicamente um truque git gc para limpar seu repositório de quaisquer arquivos que você não quer mais.
  • não é tão eficiente quanto bup ou git-BigFiles . Mas é, respectivamente, mais adequado para o que você está tentando fazer e mais off-the-shelf. Que são susceptíveis de ter problemas com centenas de milhares de arquivos pequenos ou com arquivos na faixa de gigabytes, mas ler sobre soluções alternativas.

Adicionando os arquivos binários

Antes de começar a se certificar de que você cometeu todas as suas alterações, a sua árvore de trabalho é até à data e o seu índice não contém quaisquer alterações não confirmadas. Pode ser uma boa idéia para empurrar todas as suas filiais locais para o controle remoto (github etc.) no caso de qualquer desastre deve acontecer.

  1. Criar um novo ramo órfão. git checkout --orphan binaryStuff irá fazer o truque. Isso produz um ramo que é totalmente desconectado de qualquer outro ramo, eo primeiro cometer você vai fazer neste ramo terá nenhum pai, o que irá torná-lo uma raiz cometer.
  2. Limpe seu índice usando git rm --cached * .gitignore.
  3. Respire fundo e eliminar toda árvore de trabalho usando rm -fr * .gitignore. diretório .git interna permanecerá intocado, porque o curinga * não combiná-lo.
  4. Copiar em sua VeryBigBinary.exe, ou o seu li VeryHeavyDirectory /.
  5. Adicione-&& cometê-lo.
  6. Agora torna-se complicado - se você empurrá-lo para o controle remoto como um ramo todos os seus desenvolvedores vai baixá-lo na próxima vez que eles invocam git fetch entupimento sua conexão. Você pode evitar isso, empurrando um tag em vez de um ramo. Isso ainda pode impactar armazenamento largura de banda e do sistema de arquivos do seu colega se eles têm o hábito de git fetch <remote> --tags digitação, mas a ler para uma solução alternativa. Vá em frente e git tag 1.0.0bin
  7. Empurre a sua tag órfã git push <remote> 1.0.0bin.
  8. Apenas para que você nunca empurrar o seu ramo de binário por acidente, você pode excluí-lo git branch -D binaryStuff. Seu comprometer não será marcado para coleta de lixo, porque uma tag apontando órfão nele 1.0.0bin é suficiente para mantê-lo vivo.

Verificar se o arquivo binário

  1. Como faço (ou os meus colegas) obter o VeryBigBinary.exe check-out para a árvore de trabalho atual? Se o seu atual ramo de trabalho é, por exemplo mestre você pode simplesmente git checkout 1.0.0bin -- VeryBigBinary.exe.
  2. Isto irá falhar se você não tem o 1.0.0bin tag órfã baixado, caso em que você vai ter que git fetch <remote> 1.0.0bin antemão.
  3. Você pode adicionar o VeryBigBinary.exe em .gitignore do seu mestre, de modo que ninguém em sua equipe vai poluir a principal história do projeto com o binário por acidente.

Completamente Eliminar o arquivo binário

Se você decidir limpar completamente VeryBigBinary.exe do seu repositório local, seu repositório remoto e repositórios do seu colega você pode apenas:

  1. Excluir a tag órfã na git push <remote> :refs/tags/1.0.0bin remoto
  2. Excluir a tag órfã localmente (exclui todas as outras tags sem referência) git tag -l | xargs git tag -d && git fetch --tags. Tomado de SO 1.841.341 com ligeira modificação.
  3. Use um git gc truque para apagar o seu agora unreferenced comprometer localmente. 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 irá apagar todos os outros commits sem referência. Tomado de SO 1.904.860
  4. Se possível, repetir o truque git gc no controle remoto. É possível se você é auto-hospedar seu repositório e pode não ser possível com alguns provedores de git, como github ou em alguns ambientes corporativos. Se você está hospedando com um provedor que não lhe dá ssh acesso à remota apenas deixá-lo ser. É possível que a infra-estrutura do seu provedor irá limpar seus unreferenced cometer em seu próprio tempo doce. Se você estiver em um ambiente corporativo você pode aconselhar o seu TI para executar um lixo cron recolhendo seu controle remoto uma vez por semana ou assim. Se eles fazem ou não não terá qualquer impacto sobre sua equipe em termos de largura de banda e armazenamento, contanto que você aconselhar os seus colegas para sempre git clone -b master --single-branch <url> vez de git clone.
  5. Todos seus colegas que querem se livrar de marcas órfãos desatualizados só precisa aplicar etapas 2-3.
  6. Você pode, em seguida, repita os passos 1-8 de Adicionando os arquivos binários para criar uma nova tag órfã 2.0.0bin. Se você está preocupado com o seu git fetch <remote> --tags colegas de digitação você pode realmente nomeá-lo novamente 1.0.0bin. Isso fará com que a próxima vez que buscar todas as marcas do velho 1.0.0bin será unreferenced e marcado para coleta de lixo seguinte (usando o passo 3). Ao tentar substituir uma tag no controle remoto você tem que usar -f assim: git push -f <remote> <tagname>

Posfácio

SVN parece lidar com deltas binários de forma mais eficiente do 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). Eu apenas testada adicionando um arquivo JPEG e rodando-a 90 graus quatro vezes (para verificar a eficácia dos deltas binários). repositório do Git cresceu 400%. repositório de SVN cresceu apenas 11%.

Portanto, parece que SVN é muito mais eficiente com arquivos binários.

Assim, a minha escolha é Git para código fonte e SVN para arquivos binários como documentação.

git clone --filter de GIT 2,19 + clones rasas

Esta nova opção pode eventualmente tornar-se a solução final para o problema de arquivo binário, se os devs Git e GitHub e torná-lo o suficiente amigável (o que, sem dúvida, ainda não alcançado para submódulos por exemplo).

Ele permite que a verdade só buscar arquivos e diretórios que você deseja para o servidor, e foi introduzida, juntamente com uma extensão do protocolo remoto.

Com isso, poderíamos primeiro fazer um clone superficial, e, em seguida, automatizar que blobs para buscar com o sistema de compilação para cada tipo de construção.

Já existe mesmo um --filter=blob:limit<size> que permite limitar o tamanho máximo de blob para buscar.

Eu tenho desde um exemplo detalhado mínimo de como os olhares de recursos como em: Como faço para clonar um subdiretório apenas um repositório git?

Eu estou procurando opiniões de como lidar com grandes arquivos binários em que o meu código fonte (aplicação web) é dependente. Quais são suas experiências / pensamentos sobre isso?

Eu, pessoalmente, ter executado em falhas de sincronização com Git com alguns dos meus anfitriões nuvem uma vez minhas aplicações web dados binários entalhado acima da 3 GB marca . Eu considerei BFT Repo Cleaner no momento, mas me senti como um hack. Desde então, tenho começado a apenas manter arquivos fora do Git competência, em vez aproveitando ferramentas específicas como o Amazon S3 para o gerenciamento de arquivos, versões e back-up.

Alguém tem experiência com múltiplos repositórios Git e gerenciá-los em um projeto?

Sim. temas Hugo são geridos principalmente desta forma. É um pouco kudgy, mas ele começa o trabalho feito.


A minha sugestão é a de escolher a ferramenta certa para o trabalho . Se é para uma empresa e você está gerenciando sua codeline no GitHub pagar o dinheiro e usar Git-LFS. Caso contrário, você pode explorar opções mais criativas, como, criptografado descentralizada usando blockchain .

As opções adicionais a serem considerados incluem Minio e s3cmd .

Tenha um olhar em camlistore . Não é realmente baseado em Git, mas acho que é mais apropriado para o que você tem que fazer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top