Migrar para o Git do controle de versão centralizado

Migrar uma equipe para o Git a partir do controle de versão centralizado requer mais do que apenas aprender novos comandos. Para oferecer suporte ao desenvolvimento distribuído, o Git armazena o histórico de arquivos e as informações de filial de forma diferente de um sistema centralizado de controle de versão. Planejar e implementar uma migração bem-sucedida para o Git a partir de um sistema centralizado de controle de versão requer a compreensão dessas diferenças fundamentais.

A Microsoft ajudou a migrar muitas equipes internas e clientes de sistemas centralizados de controle de versão para o Git. Essa experiência produziu as seguintes orientações baseadas em práticas que consistentemente são bem-sucedidas.

Etapas para uma migração bem-sucedida

Para uma migração bem-sucedida, as equipes devem:

  • Avaliar ferramentas e processos atuais.
  • Escolher uma estratégia de filial do Git.
  • Decidir se vai migrar o histórico e como.
  • Manter o sistema de controle de versão anterior.
  • Remover arquivos binários, executáveis e ferramentas do controle do código-fonte.
  • Treinar equipes em conceitos e práticas do Git.
  • Testar a migração para o Git.

Avaliar ferramentas e processos atuais

A alteração dos sistemas de controle de versão naturalmente interrompe o fluxo de trabalho de desenvolvimento com novas ferramentas e práticas. Essa interrupção pode ser uma oportunidade para melhorar outros aspectos do processo de DevOps.

As equipes devem considerar a adoção das seguintes práticas ao migrar para o novo sistema:

  • Integração contínua (CI), em que cada check-in aciona uma compilação e aprovação no teste. A CI ajuda a identificar defeitos precocemente e fornece uma forte rede de segurança para projetos.

  • Revisões de código são necessárias antes de fazer check-in do código. No modelo de filial do Git, a revisão do código de solicitação de pull faz parte do processo de desenvolvimento. As revisões de código complementam o fluxo de trabalho de CI.

  • Entrega contínua (CD) para automatizar processos de implantação. A alteração das ferramentas de controle de versão requer alterações no processo de implantação, portanto, uma migração é um bom momento para adotar um pipeline de lançamento moderno.

Escolher uma estratégia de filial do Git

Antes de migrar o código, a equipe deve selecionar uma estratégia de filial.

No Git, filiais de tópicos de curta duração permitem que os desenvolvedores trabalhem perto da filial principal e se integrem rapidamente, evitando problemas de mesclagem. Duas estratégias de filial de tópicos comuns são o GitFlow e uma variação mais simples, o GitHub Flow.

O Git desencoraja filiais de recursos isoladas e de longa duração, que tendem a atrasar as fusões até que a integração se torne difícil. Usando técnicas modernas de CD, como sinalizadores de recursos, as equipes podem integrar o código à filial principal rapidamente, mas ainda manter os recursos em andamento ocultos dos usuários até que sejam concluídos.

As equipes que atualmente usam uma estratégia de filial de recursos de longa duração podem adotar sinalizadores de recursos antes de migrar para o Git. O uso de sinalizadores de recursos simplifica a migração, minimizando o número de filiais a serem migradas. Quer usem filiais de recursos ou sinalizadores de recursos, as equipes devem documentar o mapeamento entre filiais herdadas e novas filiais do Git, para que todos entendam onde devem confirmar seu novo trabalho.

Decidir se deseja migrar o histórico

As equipes podem ficar tentadas a migrar seu histórico de código-fonte existente para o Git. Várias ferramentas afirmam migrar um histórico completo de todas as filiais de uma ferramenta centralizada para o Git. Uma confirmação do Git parece mapear relativamente bem para o conjunto de alterações ou modelo de check-in que a ferramenta de controle de versão anterior usava.

No entanto, esse mapeamento tem algumas limitações sérias.

  • Na maioria dos sistemas centralizados de controle de versão, as filiais existem como pastas no repositório. Por exemplo, a filial principal pode ser uma pasta chamada /trunk e outras filiais são pastas como /branch/one e /branch/two. Em um repositório do Git, as filiais incluem todo o repositório, portanto, uma tradução individualizada é difícil.

  • Em alguns sistemas de controle de versão, uma marcação ou rótulo é uma coleção que pode conter vários arquivos na árvore, até mesmo arquivos em diferentes versões. No Git, uma marcação é um instantâneo de todo o repositório em um ponto específico no tempo. Uma marcação não pode representar um subconjunto do repositório ou combinar arquivos em versões diferentes.

  • A maioria dos sistemas de controle de versão armazena detalhes sobre a maneira como os arquivos mudam entre as versões, incluindo tipos de alteração refinados, como renomear, cancelar exclusão e reversão. O Git armazena versões como instantâneos de todo o repositório, e metadados sobre a maneira como os arquivos foram alterados não estão disponíveis.

Essas diferenças significam que uma migração de histórico completo será, na melhor das hipóteses, deficitária e, possivelmente, enganosa. Dada essa característica, o esforço envolvido e a relativa raridade do uso do histórico, recomenda-se que a maioria das equipes evite importar o histórico. Em vez disso, as equipes devem fazer uma migração de ponta, trazendo apenas um instantâneo da versão de filial mais recente para o Git. Para a maioria das equipes, o tempo é mais bem gasto em áreas da migração que têm um maior retorno sobre o investimento, como a melhoria de processos.

Manter o antigo sistema de controle de versão

Durante e após uma migração, os desenvolvedores ainda podem precisar acessar o histórico de controle de versão anterior. Embora o histórico de controle de versão anterior se torne menos relevante com o tempo, ainda é importante poder consultá-lo. Ambientes altamente regulamentados podem ter requisitos legais e de auditoria específicos para o histórico de controle de versão.

Especialmente para equipes que fazem apenas uma migração de ponta, é altamente recomendável manter o sistema anterior indefinidamente. Defina o sistema de controle de versão antigo como somente leitura após a migração.

Grandes equipes de desenvolvimento e ambientes regulamentados podem colocar trilhas no Git que apontam para o antigo sistema de controle de versão. Um exemplo simples é um arquivo de texto adicionado como a primeira confirmação na raiz de um repositório do Git, antes da migração de ponta, que aponta para o URL do servidor de controle de versão antigo. Se muitas filiais forem migradas, um arquivo de texto em cada filial deverá explicar como as filiais migraram do sistema antigo. Trilhas também são úteis para desenvolvedores que começam a trabalhar em um projeto depois que ele foi migrado e não estão familiarizados com o antigo sistema de controle de versão.

Remover arquivos binários e ferramentas

O modelo de armazenamento do Git é otimizado para controle de versão de arquivos de texto e código-fonte, que são compactos e altamente compactáveis. Os arquivos binários geralmente são grandes e, uma vez adicionados a um repositório, permanecem no histórico do repositório e em todos os clones futuros. Devido à maneira como o Git armazena o histórico, os desenvolvedores devem evitar adicionar arquivos binários aos repositórios, especialmente binários que são muito grandes ou que mudam com frequência. A migração para o Git é uma oportunidade de remover esses binários da base de código.

Também é recomendável excluir bibliotecas, ferramentas e saída de compilação dos repositórios. Em vez disso, use sistemas de gerenciamento de pacotes como o NuGet para gerenciar dependências.

Ativos como ícones e ilustrações talvez precisem se alinhar a uma versão específica do código-fonte. Ativos pequenos e pouco alterados, como ícones, não sobrecarregam o histórico, e você pode incluí-los diretamente em um repositório. Para armazenar ativos grandes ou que mudam com frequência, use a extensão LFS (Large File Storage) do Git. Para obter mais informações sobre como gerenciar arquivos grandes no GitHub, consulte Gerenciar arquivos grandes. Para o Azure Repos, confira Gerenciar e armazenar arquivos grandes no Git.

Fornecer treinamento

Um dos maiores desafios na migração para o Git é ajudar os desenvolvedores a entender como o Git armazena as alterações e como as confirmações formam o histórico de desenvolvimento. Não basta preparar uma folha de referências que mapeie comandos antigos para comandos do Git. Os desenvolvedores precisam parar de pensar no histórico de controle de versão em termos de um modelo centralizado e linear e entender o modelo de histórico do Git e o gráfico de confirmação.

As pessoas aprendem de maneiras diferentes, então você deve fornecer vários tipos de materiais de treinamento. O treinamento ao vivo prático com um instrutor especializado funciona bem para algumas pessoas. O guia Pro Git é um excelente ponto de partida que está disponível gratuitamente online.

Os cursos de treinamento prático gratuitos disponíveis incluem:

As organizações devem trabalhar para identificar especialistas em Git nas equipes, capacitá-los a ajudar os outros e incentivar outros membros da equipe a fazerem perguntas a eles.

Testar a migração

Depois que as equipes atualizarem os processos, analisarem o código e treinarem seus membros, é hora de migrar o código-fonte. Se você fizer uma migração de ponta ou migrar o histórico, é importante fazer uma ou mais migrações de teste em um repositório de teste. Antes de fazer uma migração final, certifique-se de que:

  • Todos os arquivos de código tenham sido migrados.
  • Todas as filiais estejam disponíveis.
  • Não haja binários perdidos no repositório.
  • Os usuários têm as permissões apropriadas para realizar fetch e push.
  • As compilações foram bem-sucedidas e todos os testes foram aprovados.

Migrar o código

Faça a migração final durante o horário de folga, idealmente entre marcos quando houver tempo de inatividade natural. A migração no final de uma sprint pode causar problemas enquanto os desenvolvedores estão tentando concluir o trabalho. Tente migrar em um fim de semana, quando ninguém precisa fazer check-in.

Planeje uma transição firme do antigo sistema de controle de versão para o Git. Tentar operar vários sistemas em paralelo significa que os desenvolvedores podem não saber onde nem como fazer check-in. Defina o sistema de controle de versão antigo como somente leitura para ajudar a evitar confusão. Sem essa salvaguarda, uma segunda migração que inclua mudanças provisórias pode ser necessária.

O processo de migração real varia dependendo do sistema do qual você está migrando. Para obter informações sobre como migrar do Controle de Versão do Team Foundation, consulte Migrar do TFVC para o Git.

Lista de verificação de migração

Fluxos de trabalho da equipe:

  • Determine como as compilações serão executadas.
  • Decida quando os testes serão executados.
  • Desenvolva um processo de gerenciamento de lançamentos.
  • Mova revisões de código para solicitações pull.

Estratégias de filiais:

  • Escolha uma estratégia de filial do Git.
  • Documente a estratégia de filial, por que ela foi selecionada e como as filiais herdadas são mapeadas.

Histórico:

  • Decida por quanto tempo manter o controle de versão herdado em execução.
  • Identifique filiais que precisam migrar.
  • Se necessário, crie trilhas para ajudar os engenheiros a navegar de volta para o sistema herdado.

Binários e ferramentas:

  • Identifique quais binários e arquivos indistinguíveis devem ser removidos do repositório.
  • Decida uma abordagem para arquivos grandes, como o Git-LFS.
  • Decida uma abordagem para fornecer ferramentas e bibliotecas, como o NuGet.

Treinamento:

  • Identifique materiais de treinamento.
  • Planeje eventos de treinamento, materiais escritos e vídeos.
  • Identifique os membros da equipe para servir como especialistas locais do Git.

Migração de código:

  • Faça várias execuções de teste para garantir que a migração ocorra sem problemas.
  • Identifique e comunique um tempo de substituição.
  • Crie o novo repositório do Git.
  • Defina o sistema antigo como somente leitura.
  • Migre primeiro a filial principal e, em seguida, quaisquer outras filiais necessárias.

Próximas etapas