Movendo um repositório SVN de vários GB para o Git

13

Atualmente, minha empresa tem uma solução do Visual Studio em um repo SVN organizado da seguinte maneira:

SolutionFolder (~3.5 GB)
|-> SolutionName.sln
|-> .. Some source code folders... (~250 MB)
|-> ThirdParty (~3 GB)
|-> Tools
    | -> Tool1
    | -> Tool2

A Ferramenta1 e a Ferramenta2 são compiladas de forma independente (têm suas próprias soluções), mas produzem executáveis ​​que são usados ​​na compilação principal. A pasta ThirdParty contém todas as dependências do projeto, incluindo alguns arquivos .lib pré-compilados com mais de 100 MB e grandes bibliotecas como o boost.

É conveniente ter tudo isso em um repositório SVN, para que (1) o desenvolvedor faça apenas um check-out e (2) não precisamos acompanhar quais versões de dependências precisamos para cada versão da compilação. Por outro lado, leva um tempo para verificar este repositório.

Qual seria a melhor maneira de mover essa estrutura de projeto para o git? Presumivelmente, é melhor excluir o ThirdParty e, possivelmente, Tools do repositório principal, mas gostaríamos de manter o ThirdParty facilmente disponível para download em uma etapa e gostamos da versão (as incompatibilidades de versão entre o repositório principal e o ThirdParty / Tools seriam ruins).

Neste ponto, não estou interessado em preservar a história, apenas em descobrir como organizar esse projeto.

ikh
fonte
Esses tamanhos estão acima dos tamanhos nos repositórios, incluindo histórico, ou são os tamanhos da cópia de trabalho local?
Doc Brown
1
O @DocBrown apenas a cópia de trabalho local, não inclui o histórico.
Ikh

Respostas:

10

Use a ferramenta adequada para o trabalho. No Windows, isso significa

Use o NuGet para dependências de terceiros

Dessa forma, você mantém as dependências de terceiros com versão, mas não sobrecarrega seu repositório com coisas desnecessárias. O check-out é muito mais rápido, e o projeto está organizado como deveria. Você pode habilitar uma opção no Visual Studio para que ele sempre baixe todas as dependências automaticamente.

Claro que você pode usar uma solução que apenas usa git (outro repositório, submódulos etc.), mas isso é apenas hacks. Fazer da maneira certa será recompensado rapidamente e deixará você com um sistema à prova de futuro.

Editar após comentários: A melhor maneira de usar o NuGet é configurar uma fonte local do NuGet, em uma unidade compartilhada ou em um servidor de pepitas completo. A instalação não deve demorar mais do que alguns minutos. Dessa forma, você pode garantir que todos os pacotes necessários estejam sempre disponíveis, independentemente de onde eles foram originados.

Wilbert
fonte
O NuGet suporta compilações de linha de comando? Estou sempre procurando por uma compilação portátil que eu possa fazer com que Jenkins construa e teste para mim. O NuGet suporta servidores de CI como o Jenkins?
uncletall
Mais um pensamento: quanto tempo você precisa para dar suporte ao seu produto? Se você precisar fornecer suporte por um período muito longo, eu não contaria com a versão correta de suas bibliotecas de terceiros para estar disponível no NuGet. Você pode ter problemas muito grandes com ferramentas como o NuGet para obter a combinação correta de ferramentas de terceiros, mesmo daqui a dois ou três anos.
uncletall
3
@uncletall: sim, o NuGet possui uma interface de linha de comando completa. E a idéia é configurar um repositório NuGet local, que pode ser apenas uma pasta em um compartilhamento de rede (chamado de "feed", docs.nuget.org/docs/creating-packages/... )
Doc Brown
Sim, presumi, é claro, que você use um espelho local. Vou atualizar a resposta.
Wilbert
2
@ikh é bastante simples e direto criar pacotes de nuget para dependências externas. Eu precisava de cerca de meio dia para empacotar 9 dependências com 50 dlls, nunca tendo feito isso antes.
Wilbert
5

Você pode usar submódulos para as ferramentas. Dessa forma, você pode mantê-los em um subdiretório como você faz agora e usar um repositório separado para versioná-los. Isso também significa que você pode clonar (fazer check-out) as ferramentas e desenvolvê-las separadamente, e que outros projetos podem confiar nesses repositórios - e em versões específicas e atualizáveis ​​deles.

Você também pode usar submódulos para bibliotecas de terceiros, mas, se possível, eu recomendaria o uso de um gerenciador de dependências.

Idan Arye
fonte
4

As entidades que você transforma em repositórios git são necessariamente as entidades que você versão e ramificação; se SolutionFolder/Tools/Tool1corresponde a uma dessas coisas, esse é o nível da entidade. Isso ocorre porque git diz respeito ao estado inteiro da árvore de diretórios a ser a entidade versionável, enquanto que com o SVN é possível (mesmo que não seja uma boa idéia) para ter um trunk, branchese tagsem qualquer lugar dentro da árvore.

Os artefatos derivados não devem ser mantidos no repositório, nem as bibliotecas externas. Existem melhores maneiras de lidar com isso. (Se você estiver trabalhando com Java, considere usar um repositório Maven privado; eles são relativamente fáceis de trabalhar e se integram muito bem a muitas outras coisas.)

Se você está acostumado a um fluxo de trabalho que possui tudo em um repo para facilitar o checkout, considere ter um script que configure as coisas.

Donal Fellows
fonte
Quais são as opções para gerenciar bibliotecas externas? Trabalhamos no Visual Studio com C ++ e C #, para que o Maven não pareça adequado. O principal problema aqui é que ter a ThirdPartypasta no repositório é muito conveniente e é difícil encontrar uma boa alternativa.
Ikh
2
@ikh: em um ambiente do Visual Studio, você normalmente usaria o Nuget para isso, docs.nuget.org , que já está incluído no VS 2012 e em versões mais recentes.
Doc Brown
2

Para ser sincero, não mudaria nada na sua configuração. É exatamente o que estamos fazendo agora. Eu estava brincando com a configuração de um repositório git separado para lidar com a lib de terceiros que usamos, mas não acho que isso pesa o custo de portabilidade. Agora, qualquer desenvolvedor pode fazer o checkout e começar sem ter que executar nenhuma etapa de configuração manual. E qualquer servidor / escravo de construção pode construir o projeto. A menos que você tenha vários repositórios compartilhando as ferramentas de terceiros, eu continuaria com sua configuração atual.

O que eu brincava era configurar as ferramentas de terceiros em um repositório separado. Então, eu tive um script em lote simples para ler um arquivo de texto com um sha1 ref e verificar a versão correta. Isso me permitiria ter diferentes versões de terceiros para diferentes projetos. Eu obtive essa ideia da ferramenta de construção do Facebook Buck. Mas no final, muitos desenvolvedores não gostam de usar ferramentas de linha de comando (loja MS VC aqui), então desisti da ideia.

Um dos principais motivos pelos quais não faz o download de suas bibliotecas de terceiros quando necessário (usando o NuGet) é que, se você precisar dar suporte ao seu produto por um longo tempo. No meu setor, precisamos fornecer atualizações para versões antigas que dependem de bibliotecas antigas de terceiros. Não queremos gastar muito tempo escolhendo quais bibliotecas podemos atualizar ou não e apenas usá-las como usadas nessa versão. Agora imagine que você usa o NuGet, oops ... a versão mais recente da lib necessária é 3,98, mas você precisa de 2,04 ..... como explicar ao seu chefe que você precisa gastar 2 meses para atualizar a versão antiga para poder para usar as últimas bibliotecas quando ele esperava uma pequena alteração!

uncletall
fonte
3
Embora eu tenha lhe dado um +1, como "deixar tudo como está" é uma solução pragmática, acho que "repos múltiplos" pode não ser o único problema. DVCS como o Git incentivam ter várias ramificações locais e, em cada ramificação, uma cópia local completa de tudo. Portanto, isso pode levar à mesma grande biblioteca de terceiros (geralmente a mesma versão!) Várias vezes como uma cópia local. Isso pode ser viável em algumas situações; em outras, posso imaginar que isso terá um impacto negativo no desempenho da ramificação e fusão.
Doc Brown
Até onde eu sei, uma ramificação é uma operação muito barata no Git que criará apenas um ponteiro e ocupará quase zero espaço.
uncletall
A menos que esteja faltando alguma coisa, os ramos são "gratuitos" no Git. Acabei de verificar meus arquivos .git / refs / heads e todos os ramos são arquivos de texto de 1 KB, o .git / logs / refs / head contém os logs em que o maior é 11 KB para o mestre. libs de terceiros e outras ferramentas. Estou muito feliz por receber o hit de 1 KB para criar uma ramificação
uncletall
1
@ MichaelT: a ramificação em si é gratuita, é claro, mas estou falando da situação em que você tem várias cópias de trabalho de ramificações diferentes na estação de trabalho local em paralelo. E se você verificar os comentários abaixo da pergunta original, o OP estava se referindo a 3 GB de ferramentas de terceiros como o tamanho da cópia de trabalho.
Doc Brown