Migrando de SVN/Mercurial para Git: ferramentas e estratégias
1. Planejamento da Migração
Antes de iniciar qualquer conversão, é essencial planejar cuidadosamente cada etapa. A migração de um sistema de controle de versão centralizado (SVN) ou descentralizado (Mercurial) para Git envolve decisões que impactam diretamente a integridade do histórico e a produtividade da equipe.
1.1. Avaliação do repositório atual
Levante informações sobre o repositório de origem: número de commits, branches ativos, tags, quantidade de autores e tamanho total. Ferramentas como svn info e hg summary ajudam nesse diagnóstico. Identifique também arquivos binários grandes que podem exigir Git LFS após a migração.
1.2. Escolha da ferramenta de conversão
Para SVN, a ferramenta oficial é git-svn, distribuída com o próprio Git. Para Mercurial, recomenda-se hg-fast-export (parte do projeto git-remote-hg). Avalie também alternativas como svn2git (Ruby) para SVN com layout complexo.
1.3. Preparação do ambiente de destino
Configure o Git com suas credenciais e crie um repositório remoto vazio (GitHub, GitLab ou servidor próprio). Decida se fará migração incremental ou corte definitivo.
# Exemplo de configuração inicial
git config --global user.name "Seu Nome"
git config --global user.email "seu@email.com"
2. Migração de SVN para Git com git-svn
2.1. Clonagem incremental do repositório SVN
O comando git svn clone baixa todo o histórico do SVN e o converte para commits Git. Use -s para layout padrão (trunk, branches, tags) ou --stdlayout explicitamente.
# Clonagem de repositório SVN com layout padrão
git svn clone https://svn.exemplo.com/projeto -s projeto-git
cd projeto-git
Para repositórios com muitos commits, use -r para clonar apenas revisões recentes e depois buscar o restante incrementalmente.
2.2. Mapeamento de autores e branches SVN
Crie um arquivo authors.txt no formato:
joao = João Silva <joao@exemplo.com>
maria = Maria Souza <maria@exemplo.com>
Passe o arquivo durante a clonagem:
git svn clone https://svn.exemplo.com/projeto -s --authors-file=authors.txt projeto-git
Branches SVN são convertidos automaticamente para branches Git. Tags SVN viram branches de tag; posteriormente você pode convertê-las em tags Git leves ou anotadas.
2.3. Finalização e limpeza
Remova os metadados SVN e envie para o repositório remoto:
git svn fetch
git branch -r # lista branches remotas SVN
git push origin --all
git push origin --tags
Para limpar referências SVN, use git svn gc e remova a configuração remota SVN com git config --remove-section svn.
3. Migração de Mercurial para Git com hg-fast-export
3.1. Instalação e preparação do ambiente
Clone o repositório git-remote-hg (ou hg-fast-export) e instale as dependências:
git clone https://github.com/frej/fast-export.git
cd fast-export
# Dependências: Python, Mercurial, Git
pip install mercurial
3.2. Execução da conversão
Crie um diretório vazio para o repositório Git de destino e execute o script:
mkdir projeto-git
cd projeto-git
git init
../fast-export/hg-fast-export.sh -r /caminho/para/repositorio-hg
O script converte todo o histórico, preservando branches, bookmarks e tags. Use -A authors.txt para mapear autores.
3.3. Verificação pós-conversão
Após a conversão, verifique a integridade:
git log --oneline | head -5
git branch -a
git tag -l
Compare o número de commits com o repositório Mercurial original. Se houver discrepância, revise o arquivo de mapeamento de autores.
4. Estratégias para Preservação do Histórico
4.1. Conversão de commits e mensagens
Tanto git-svn quanto hg-fast-export preservam autor, data e mensagem originais. Certifique-se de que o fuso horário seja mantido corretamente.
4.2. Tratamento de branches e tags
Branches SVN com nomes como branches/feature-x viram branches Git feature-x. Tags SVN (diretório tags/) viram branches tag/; converta-os para tags Git:
git for-each-ref refs/remotes/origin/tags | while read sha1 type ref; do
git tag -a -m "Tag migrada" "${ref#refs/remotes/origin/tags/}" "$sha1"
done
4.3. Lidando com merge commits e conflitos
Em repositórios SVN com merges manuais, git-svn pode não detectar todos os pais. Use --follow-parent para melhor rastreamento. Para Mercurial, merges são convertidos naturalmente.
5. Pós-Migração: Validação e Ajustes
5.1. Verificação de integridade
Execute git fsck para detectar objetos corrompidos:
git fsck --full
Compare o hash do último commit com uma referência confiável. Se possível, faça um diff entre a árvore de trabalho do repositório original e do convertido.
5.2. Correção de autores e metadados
Use git filter-repo (recomendado) para ajustes em massa:
git filter-repo --mailmap <(echo "Nome Antigo <email_antigo> Nome Novo <email_novo>")
Evite git filter-branch em repositórios grandes, pois é lento e propenso a erros.
5.3. Documentação e comunicação
Atualize o README com os novos comandos Git, revise pipelines de CI/CD e agende treinamentos para a equipe. Crie um guia de transição com exemplos práticos.
6. Boas Práticas e Armadilhas Comuns
6.1. Evitando perda de histórico
Sempre faça backup completo do repositório original antes de qualquer conversão. Use git clone --mirror para criar uma cópia exata do repositório Git convertido.
6.2. Problemas com arquivos grandes e binários
Após a migração, migre arquivos grandes para Git LFS:
git lfs migrate import --include="*.psd,*.zip" --everything
Verifique o tamanho do repositório com git count-objects -vH.
6.3. Migração contínua vs. corte definitivo
Se a equipe ainda usa SVN/Hg, planeje um período de congelamento. Alternativamente, use git svn fetch para sincronizar alterações incrementais até o corte final.
7. Casos Especiais e Ferramentas Alternativas
7.1. Repositórios SVN com layout não padrão
Use opções específicas para mapear diretórios:
git svn clone https://svn.exemplo.com/projeto \
--trunk=main --branches=releases --tags=versions \
projeto-git
7.2. Migração de Mercurial com extensões
Extensões como evolve e mq (patch queues) podem complicar a conversão. Para mq, exporte patches manualmente antes de converter. Para evolve, use hg evolve --cleanup antes da migração.
7.3. Ferramentas complementares
Considere git-remote-svn para acesso bidirecional (leitura/escrita) entre Git e SVN. svn2git (versão Ruby) é útil para repositórios SVN com histórico muito antigo. cvs2git atende quem ainda usa CVS.
Referências
- Documentação oficial do git-svn — Guia completo de uso do
git-svn, incluindo opções de clonagem e mapeamento de autores. - Projeto hg-fast-export (fast-export) — Ferramenta oficial para conversão de Mercurial para Git, com exemplos de uso e tratamento de branches.
- Guia de migração do GitLab: SVN para Git — Tutorial prático com etapas de migração SVN para Git usando GitLab como destino.
- Git LFS (Large File Storage) – Documentação oficial — Como gerenciar arquivos grandes após a migração, com comandos de instalação e migração.
- Atlassian: Migrando de SVN para Git — Tutorial detalhado da Atlassian com estratégias de migração, mapeamento de autores e validação pós-conversão.