O que fazer com a grande história do svn ao mudar para o git?

23

Editar: ao contrário de algumas perguntas semelhantes, como Mover um repositório SVN de vários GB para o Git ou /programming/540535/managing-large-binary-files-with-git Meu cenário não envolve vários subprojetos que pode ser facilmente convertido em submodelos git, nem em alguns arquivos binários muito grandes que são adequados para o anexo git. É um repositório único em que os binários são o conjunto de testes que se acopla ao código-fonte principal da mesma revisão, como se fossem compilar ativos de tempo, como gráficos.

Estou investigando a troca de um repositório de código antigo / de tamanho médio / grande (50 usuários, revisões de 60k, histórico de 80Gb, cópia de trabalho de 2Gb) do svn. À medida que o número de usuários cresce, há uma grande quantidade de rotatividade no tronco, e os recursos geralmente são distribuídos em vários commits, dificultando a revisão do código. Além disso, sem ramificação, não há como "bloquear" o código incorreto; as revisões só podem ser feitas após o comprometimento do tronco. Estou investigando alternativas. Eu esperava que pudéssemos mudar para o git, mas estou tendo alguns problemas.

O problema com o repo atual, tanto quanto o git, é o tamanho. Há muito lixo velho lá, e limpá-lo com --filter-branch ao converter para git pode reduzi-lo em tamanho por uma ordem de magnitude, para cerca de 5 a 10 GB. Isso ainda é muito grande. A maior razão para o tamanho grande do repositório é que existem muitos documentos binários sendo introduzidos nos testes. Esses arquivos variam entre .5mb e 30mb, e existem centenas. Eles também têm muitas mudanças. Eu observei os submódulos, o anexo git etc., mas ter os testes em um submódulo parece errado, assim como o anexo de muitos arquivos para os quais você deseja um histórico completo.

Portanto, a natureza distribuída do git é realmente o que está me impedindo de adotá-lo. Eu realmente não me importo com a distribuição, só quero as ramificações baratas e os poderosos recursos de mesclagem. Como suponho que 99,9% dos usuários do git usem, usaremos um repositório central abençoado e vazio.

Não sei ao certo por que cada usuário precisa ter um histórico local completo ao usar o git? Se o fluxo de trabalho não for descentralizado, o que esses dados estão fazendo nos discos dos usuários? Eu sei que nas versões recentes do git você pode usar um clone superficial com apenas histórico recente. Minha pergunta é: é viável fazer isso como o modo padrão de operação para uma equipe inteira? O git pode ser configurado para ser sempre superficial para que você possa ter um histórico completo apenas centralmente, mas por padrão os usuários têm apenas 1000 rotações do histórico? A opção para isso, é claro, seria converter apenas 1000 rotações em git e manter o repositório svn para arqueologia. Nesse cenário, no entanto, encontraríamos o mesmo problema novamente após as próximas milhares de revisões nos documentos de teste.

  • O que é uma boa prática recomendada para usar git com grandes repos que contém muitos arquivos binários que você não quer que a história de? A maioria das melhores práticas e tutoriais parece evitar esse caso. Eles resolvem o problema de poucos binários enormes ou propõem a remoção total dos binários.
  • A clonagem superficial é utilizável como um modo normal de operação ou é um "hack"?
  • Os sub-módulos podem ser usados ​​para código em que você tem uma dependência estreita entre a revisão principal de origem e a revisão do sub-módulo (como dependências binárias em tempo de compilação ou um conjunto de testes de unidade)?
  • Qual o tamanho "grande demais" para um repositório git (local)? Devemos evitar a troca se conseguirmos reduzir para 4 GB? 2GB?
Anders Forsgren
fonte
possível duplicata de Mover um repo multi-GB SVN para Git
mosquito
Pesquisei bastante informações sobre isso e não encontrei nada que respondesse à minha pergunta. Na questão vinculada, os workaounrds (submódulos, anexo etc.) funcionariam muito melhor do que no meu cenário.
Anders Forsgren
1
Git LFS
CodesInChaos
O Perforce pode ser uma opção melhor do que o git, pois foi projetado para lidar com muitos arquivos binários grandes, portanto usados ​​por muitos desenvolvedores de jogos. Plasticscm também vale a pena olhar.
21416 Ian
Apenas um aspecto: evite os sub-módulos git, se puder, pois eles complicam demais o sistema de compilação (o que já é complicado no seu caso).
IgorGanapolsky

Respostas:

10

Uau, essa é uma pergunta longa (e um problema complexo). Vou tentar tentar.

Não sei ao certo por que cada usuário precisa ter um histórico local completo ao usar o git?

Esta é uma decisão central de design com o git. Pelas razões exatas que você precisaria perguntar ao autor (Linus Torvalds), mas até onde eu sei, o principal motivo é a velocidade: ter tudo local (em um disco rápido ou mesmo em cache na RAM) torna as operações na história muito mais rápidas. evitando o acesso à rede.

A maior razão para o tamanho grande do repositório é que existem muitos documentos binários sendo introduzidos nos testes. Esses arquivos variam entre .5mb e 30mb, e existem centenas. Eles também têm muitas mudanças.

É nesse ponto que eu pensaria primeiro. Ter tantos arquivos binários em constante mudança no controle de origem parece problemático para mim (mesmo com o SVN). Você não pode usar uma abordagem diferente? Idéias:

  • Diferentemente do código fonte, um arquivo binário de 3 MB provavelmente não é escrito à mão. Se alguma ferramenta / processo o gerar, considere integrá-lo à sua compilação, em vez de armazenar os dados.

  • Se isso não for prático, os arquivos binários normalmente são melhores em um repositório de artefatos (como Artifactory for Maven & co.). Talvez essa seja uma opção para você.

Examinei os submódulos, o anexo git, etc.

Na verdade, parece que o git-anexo se encaixaria perfeitamente. O git-anexo basicamente permite armazenar o conteúdo do arquivo fora de um repositório git (o repositório contém um espaço reservado). Você pode armazenar o conteúdo do arquivo de várias maneiras (repositório central do git, unidade compartilhada, armazenamento em nuvem ...) e pode controlar o conteúdo que deseja ter localmente.

Você talvez entendeu mal como o git-anexo funciona? O git-anexo armazena o histórico completo de todos os arquivos que gerencia - apenas permite escolher qual conteúdo do arquivo você deseja ter localmente.

Por fim, sobre suas perguntas:

Qual é uma boa prática para usar o git com repositórios grandes contendo muitos arquivos binários para os quais você deseja histórico?

Na minha experiência, as opções geralmente são:

  • evite a necessidade de binários no repositório (gere-os sob demanda, armazene-os em outro local)
  • use git-anexo (ou uma solução semelhante, como Git LFS)
  • viva com um grande repositório (nem todas as operações git são afetadas por arquivos grandes, e se você tiver um computador e uma unidade rápidos, pode ser bastante viável)

A clonagem superficial é utilizável como um modo normal de operação ou é um "hack"?

Isso pode ser factível; no entanto, acho que isso não resolverá o seu problema:

  • você perderia os benefícios do git resultantes de um histórico completo, como uma pesquisa rápida do histórico
  • mesclagens podem se tornar complicadas, porque AKAIK você deve ter pelo menos o histórico de volta ao ponto de ramificação para mesclar
  • os usuários precisariam clonar periodicamente para manter o tamanho do clone pequeno
  • é apenas uma maneira incomum de usar o git, então você provavelmente terá problemas com muitas ferramentas

Qual o tamanho "grande demais" para um repositório git (local)? Devemos evitar a troca se conseguirmos reduzir para 4 GB? 2GB?

Isso depende da estrutura do repositório (poucos / muitos arquivos etc.), do que você deseja fazer, do quão robustos são seus computadores e da sua paciência :-).

Para lhe dar uma idéia rápida: No meu laptop (recente, mas de baixa especificação), o envio de um arquivo de 500 MB leva de 30 a 60 anos. Apenas listar o histórico (git log etc.) não é afetado por arquivos grandes; coisas como "git log -S", que deve verificar o conteúdo do arquivo, são muito lentas - no entanto, a velocidade é predominantemente dominada pela E / S, portanto não é realmente culpa do git.

Em um repositório de 3 GB com várias revisões, "git log -S" leva cerca de um minuto.

Então, eu diria que alguns GB estão ok, embora não sejam ideais. Provavelmente, mais de 10 a 20 GB estão aumentando, mas pode ser possível - você precisaria tentar.

sleske
fonte
Obrigado pela sua resposta detalhada. Certamente analisarei o anexo para documentos de teste. A barra para "desempenho razoável" provavelmente é "próxima do svn", ou seja, se for significativamente mais lenta para qualquer operação, haverá muito atrito para alternar.
Anders Forsgren
Eu acho que o Git LFS também pode ser usado para armazenamento de arquivos binários grandes.
IgorGanapolsky
@IgorG .: Sim, o Git LFS é uma alternativa, existem outras. Obrigado por apontar, editei minha postagem.
sleske
4

À medida que o número de usuários cresce, há uma grande quantidade de rotatividade no tronco, e os recursos geralmente são distribuídos em vários commits, dificultando a revisão do código. Além disso, sem ramificação, não há como "bloquear" o código incorreto; as revisões só podem ser feitas após o comprometimento do tronco

Mudar para o git não resolverá esses problemas, eles são problemas de como você usa a ferramenta e, se você usar o git da mesma maneira, os problemas permanecerão.

Você pode ramificar no svn com a mesma facilidade no git, e a mesclagem geralmente é tão fácil quanto tem as mesmas armadilhas. O Git foi projetado para trabalhar com o código-fonte do kernel, portanto, ele fez algumas suposições que podem não se aplicar a todos os casos, como o seu, com grandes binários e históricos massivos. A intenção por trás de um DVCS é que todo usuário efetivamente trabalhe sozinho e colabore posteriormente - ou seja, eles tenham seu próprio repositório (uma cópia), trabalhem como quiserem e depois enviem as alterações para quem quiser. Um sistema federado usado no desenvolvimento do kernel do linux é perfeito para isso - você envia suas alterações para o próximo cara da cadeia que o mescla com sua base de código e o empurra para o próximo cara até chegar a Linus que o lança no lançamento. A maioria das equipes usa o git da mesma forma, mas com apenas um cara upstream, que geralmente é um repositório 'ouro' do lado do servidor,

Então, eu gostaria de mudar o seu fluxo de trabalho primeiro, migrando apenas para o git quando você tiver uma maneira melhor de trabalhar. Implemente ramificação e mesclagem no SVN, se você não renomear arquivos ou diretórios, a mesclagem funciona muito bem.

gbjbaanb
fonte
4
"Você pode se ramificar no svn com a mesma facilidade no git, e a fusão geralmente é tão fácil quanto tem as mesmas armadilhas", uau, essa é uma afirmação realmente controversa. Mesclar no git, na minha opinião, geralmente é fácil e no svn geralmente é um pesadelo, mesmo nas versões após a introdução de uma tentativa incompleta de rastreamento de mesclagem (sim, eu trabalho com o git, não apenas neste repositório). O fluxo de trabalho que queremos ter é aquele em que você cria uma ramificação de recurso, revisão de código / criação de IC nessa ramificação. Simplesmente não há como fazer isso no SVN sem grande frustração.
Anders Forsgren
2
não, fazemos isso o tempo todo aqui. Estou apenas passando as 157 ramificações no meu repositório SVN para ver quais podem ser excluídas. Ramificamos, desenvolvemos, revisamos e, em seguida, mesclamos quase diariamente aqui, ocasionalmente enfrentamos problemas, mas isso sempre é corrigido retirando uma nova ramificação do tronco e mesclando as alterações a ele (para que possa ser facilmente mesclado novamente ao tronco mais tarde) . Isso realmente só se aplica a ramos antigos. Se você tem uma grande frustração, não entende bem o suficiente. O Git também lhe dará grandes frustrações.
Gbjbaanb
2
Eu simplesmente não experimento. Ao trabalhar com o git (como eu disse que faço, mas em repositórios menores), acho bastante fácil e natural fazer ramificações, rebasing, squash e mesclagem. "Conflitos de árvore após renomear" etc. são muito mais raros, e o fato de que você pode emular um histórico linear e simples (via rebase + squash etc.) é muito importante. Então: para manter a questão no tópico (git com grandes repositórios): Vamos supor que o svn não suporte o fluxo de trabalho que eu preciso, e o git sim.
Anders Forsgren
1
Em uma empresa anterior, usamos o git, e eu conheço alguém que costumava perder seu trabalho regularmente, por isso não é um sistema perfeito de forma alguma! O SVN também não é, mas o SVN se encaixa muito melhor às suas circunstâncias do que o git IMHO, e funciona. No tópico, como fazer o git funcionar como você deseja ... Não tenho certeza se isso funcionará, desculpe.
Gbjbaanb
7
@gbjbaanb Se alguém está perdendo seu trabalho com o Git, está fazendo algo terrivelmente errado.
RubberDuck
2

Veja a lista de discussão do GCC. A migração da árvore de fontes do compilador GCC do SVN para o GIT é discutida agora (agosto e setembro de 2015), mantendo o histórico do GCC. Veja, por exemplo, repositório para o mecanismo de conversão e Critérios de aceitação para os threads de correio de conversão git ; você encontrará referências a ferramentas e procedimentos relacionados à conversão (o que não é tão simples quanto parece; a conversão de um histórico tão grande de base de código precisa de 36 horas e cerca de 64Gbytes de RAM, IIRC)

Basile Starynkevitch
fonte
Você quis dizer migrar do SVN para o Git? Migrar de um sistema de controle de versão para um conjunto de compiladores parece um pouco ... estranho. Além disso, isso parece mais um comentário do que uma resposta.
8bittree
Sim. Desculpe pelo erro de digitação.
Basile Starynkevitch
Obrigado. 36 horas soa como uma brisa, a nossa pode converter em um par de semanas ...
Anders Forsgren
2

Se a conversão de todo o repositório SVN em Git resultar em um enorme repositório que não é possível clonar, você pode tentar usar o SubGit para criar espelhos menores do Git para certas partes do seu repositório Subversion.

Por exemplo, você pode importar e sincronizar alguns subdiretórios do seu repositório SVN http://domain/repos/trunk/project/src:

subgit configure --layout auto --trunk trunk/project/src http://domain/repos project.git
edit project.git/subgit/config
edit project.git/subgit/authors.txt
subgit install project.git

Para mais detalhes sobre o uso do SubGit, consulte a documentação .

Assim que você tiver o espelho Git desse diretório, poderá usar o repositório Git para enviar novas alterações que serão refletidas imediatamente no repositório SVN. Como você sincroniza apenas determinada parte do repositório SVN que reduz significativamente o tamanho do repositório Git convertido e ainda é possível criar ramificações, mesclá-las, empregar qualquer fluxo de trabalho do lado do Git.

Como alternativa, você pode importar o repositório SVN inteiro, mas excluir arquivos grandes da sincronização:

subgit configure --layout auto --trunk trunk http://domain/repos project.git
edit project.git/subgit/config
...
[svn]
    excludePath = *.bin
    excludePath = *.iso
...
edit project.git/subgit/authors.txt
subgit install project.git

O repositório Git resultante deve ter um tamanho razoável e os desenvolvedores ainda podem usar o Git para enviar suas alterações ao repositório Subversion.

Observe que esta solução deve funcionar bem para você, se você estiver pronto para manter o servidor Subversion em execução e usar o Git ao lado do seu repositório SVN.

Isenção de responsabilidade: sou um dos desenvolvedores do SubGit; SubGit é um software comercial com várias opções gratuitas disponíveis.

vadishev
fonte
1

Abordarei sua situação da seguinte maneira:

1) Inicialize um repositório git no mesmo diretório que seu repositório SVN. Faça git inite git remote add origininicie esse repositório Git. Dessa forma, você pode continuar se comprometendo no SVN e no git separadamente, sem lidar com uma conversão completa de um para o outro até estar pronto.

2) Use ativamente as ferramentas bfg e filter-branch para tentar reduzir seu repositório git, conforme discutido aqui: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html

3) Use git-anexo, ou Git LFS, ou apenas um servidor de armazenamento externo para seus binários grandes (transportando os arquivos usando scripts de shell no momento da construção).

4) Quando estiver familiarizado com a estratégia de mesclagem / ramificação no seu repositório git e com o tamanho do seu repositório git, você poderá fazer uma migração completa do seu svn para o git.

Espero que isto ajude.

IgorGanapolsky
fonte