Migração entre plataformas: GitHub, GitLab, Bitbucket

1. Introdução à Migração entre Plataformas Git

A decisão de migrar entre plataformas de hospedagem Git — GitHub, GitLab ou Bitbucket — geralmente é motivada por fatores estratégicos. Empresas podem buscar redução de custos (GitLab self-hosted vs. GitHub Enterprise), necessidade de maior privacidade e controle de dados, ou funcionalidades específicas como CI/CD integrada (GitLab CI) ou integração nativa com Atlassian (Bitbucket + Jira).

Cada ecossistema oferece vantagens distintas: o GitHub é líder em comunidade open source e integrações; o GitLab se destaca pelo DevOps completo em uma única aplicação; o Bitbucket brilha em ambientes corporativos Atlassian. Os desafios incluem preservar o histórico de commits, migrar issues e pull requests, recriar pipelines de CI/CD e reconfigurar permissões de equipe. Riscos como perda de dados, downtime e resistência da equipe precisam ser gerenciados com planejamento cuidadoso.

2. Preparação para a Migração

Antes de qualquer movimento, realize uma auditoria completa do repositório atual. Liste todos os branches (incluindo remotos), tags e verifique a integridade do histórico de commits. Documente integrações ativas: pipelines CI/CD (GitHub Actions, GitLab CI, Bitbucket Pipelines), webhooks para Slack ou Discord, hooks de servidor e serviços de terceiros como SonarQube ou Snyk.

Crie um backup completo utilizando clone mirror, que preserva todos os branches, tags e referências:

# Backup completo do repositório (modo mirror)
git clone --mirror https://github.com/usuario/repo-origem.git
cd repo-origem.git
git bundle create backup-repo.bundle --all

Armazene o bundle em local seguro. Verifique o backup:

# Verificar integridade do bundle
git bundle verify backup-repo.bundle

3. Migração do Repositório (Código e Histórico)

O método mais seguro para migrar o repositório mantendo todo o histórico é o push mirror. Primeiro, crie um repositório vazio na plataforma de destino (sem README, .gitignore ou licença). Em seguida:

# Clonagem mirror do repositório de origem
git clone --mirror https://github.com/usuario/repo-origem.git
cd repo-origem.git

# Adicionar remote de destino
git remote add destino https://gitlab.com/usuario/repo-destino.git

# Push de todos os branches e tags
git push --mirror destino

Para verificar a integridade, clone o repositório de destino e compare o log:

# Verificação no destino
git clone https://gitlab.com/usuario/repo-destino.git
cd repo-destino
git log --oneline --all | head -5
git branch -a
git tag -l

Se houver LFS (Large File Storage), migre separadamente:

# Migração de arquivos LFS
git lfs fetch --all origem
git lfs push --all destino

4. Migração de Issues, Pull Requests e Wiki

Plataformas modernas oferecem ferramentas nativas de importação. O GitHub Importer aceita URLs de repositórios GitLab e Bitbucket. O GitLab possui importação direta de GitHub e Bitbucket Cloud. Para migração de issues e PRs, ferramentas de terceiros como gitea-github-migrator podem ser úteis:

# Exemplo com gitea-github-migrator (Node.js)
npx gitea-github-migrator \
  --source https://github.com/usuario/repo-origem \
  --destination https://gitlab.com/usuario/repo-destino \
  --token-origem ghp_seu_token_github \
  --token-destino glpat_seu_token_gitlab

Para wikis, que são repositórios Git separados, clone e push diretamente:

# Migração de wiki
git clone https://github.com/usuario/repo-origem.wiki.git
cd repo-origem.wiki.git
git remote add destino https://gitlab.com/usuario/repo-destino.wiki.git
git push --mirror destino

5. Configuração de Ambientes e Integrações

Após a migração do código, recrie os pipelines CI/CD. Cada plataforma usa sintaxe diferente: YAML do GitHub Actions, .gitlab-ci.yml ou bitbucket-pipelines.yml. Exemplo de pipeline equivalente:

# GitHub Actions (antigo)
name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm install && npm test

# GitLab CI (novo)
stages:
  - test
test_job:
  stage: test
  script:
    - npm install
    - npm test

Configure webhooks manualmente nas configurações do repositório de destino. Ajuste branches protegidos (proteção contra push direto, exigência de reviews) e regras de merge (squash, rebase). Use APIs REST para automação:

# GitLab API para proteger branch main
curl --request PUT \
  --header "PRIVATE-TOKEN: glpat_seu_token" \
  --url "https://gitlab.com/api/v4/projects/ID_PROJETO/protected_branches/main" \
  --data "push_access_level=40&merge_access_level=40"

6. Migração de Usuários e Equipes

O mapeamento de contribuidores é crítico. O Git preserva autores nos commits (nome e email), mas issues e PRs ficam associados a usuários da plataforma. No GitHub, use git log --format="%an <%ae>" para listar autores. No GitLab, durante a importação, é possível mapear usuários automaticamente se os emails coincidirem.

Recrie grupos e times manualmente ou via API. Exemplo com Bitbucket Cloud:

# Bitbucket API para criar grupo
curl -X POST \
  -u usuario:senha \
  -H "Content-Type: application/json" \
  -d '{"name": "desenvolvedores", "permission": "write"}' \
  https://api.bitbucket.org/2.0/workspaces/workspace/groups

Notifique a equipe com antecedência sobre a migração, forneça treinamento sobre a nova plataforma e compartilhe documentação de acesso.

7. Validação Pós-Migração e Cutover

Realize testes abrangentes antes do cutover oficial. Peça para membros da equipe clonar, fazer push e pull do novo repositório:

# Teste de clone e push
git clone https://gitlab.com/usuario/repo-destino.git
cd repo-destino
echo "# Teste pós-migração" >> README.md
git add README.md
git commit -m "teste: verificação pós-migração"
git push origin main

Verifique funcionalidades críticas: issues criam corretamente? Pull requests funcionam? Pipelines disparam? Teste webhooks com serviços externos. Se tudo estiver OK, redirecione URLs (DNS, repositórios antigos com redirect) e comunique o cutover oficial.

Tenha um plano de rollback: mantenha o repositório de origem ativo por pelo menos 30 dias e documente os passos para reverter:

# Rollback: restaurar do backup
cd repo-origem.git
git push --mirror https://github.com/usuario/repo-origem.git

8. Boas Práticas e Dicas Finais

Mantenha um repositório espelho (mirror) da origem por pelo menos um mês após a migração, permitindo consultas a histórico antigo. Documente todo o processo em um runbook, incluindo comandos executados, problemas encontrados e soluções. Automatize migrações futuras com scripts shell ou ferramentas como Ansible.

Para migrações recorrentes (ex: migração trimestral de dados), considere usar git remote set-url para alternar entre plataformas durante o período de transição. Sempre teste em um ambiente de staging primeiro.

Lembre-se: a migração bem-sucedida não é apenas técnica — é também cultural. Envolva a equipe, colete feedback e ajuste processos. Com planejamento adequado, a troca de plataforma Git pode ser suave e trazer os benefícios esperados.

Referências