Branch de maneira estratégica

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

O código-fonte é um ativo importante em seu trabalho de desenvolvimento. Mas pode ser um desafio gerenciar e evoluir efetivamente os arquivos de código-fonte quando vários desenvolvedores trabalham simultaneamente nas atualizações dos arquivos. Você pode usar um sistema de controle de versão para armazenar o código-fonte em repositórios compartilhados, isolar trabalhos paralelos de desenvolvimento, integrar as alterações de código e recuperar versões anteriores dos arquivos. Um elemento-chave no controle de versão é a ramificação que permite o desenvolvimento simultâneo. Se você ramificar estrategicamente, poderá manter a ordem e a consistência de várias versões do software.

O Team Foundation fornece um sistema flexível e confiável de controle de versão. Você pode usar o controle de versão do Team Foundation para gerenciar várias revisões durante o desenvolvimento do código-fonte, documentos, itens de trabalho e outras as informações essenciais nas quais sua equipe está trabalhando.

Como sua equipe gerencia o código enquanto introduz várias alterações simultaneamente em várias versões do projeto?

Quando você trabalha com um sistema de controle de versão, é preciso considerar como configurar uma estrutura de ramificação. Você pode criar uma ramificação pelo espelhamento do arquivo de código-fonte. Depois, você pode alterar a ramificação sem afetar o código-fonte. Por exemplo, como a estrutura de ramificação na ilustração a seguir mostra, a ramificação PRINCIPAL contém a funcionalidade completa que passou no teste de integração, e a ramificação DESENVOLVIMENTO contém o código que está em construção. Quando uma nova funcionalidade na ramificação DESENVOLVIMENTO é concluída e pode passar nos testes de integração, você poderá promover o código da ramificação DESENVOLVIMENTO para a ramificação PRINCIPAL. Esse processo é conhecido como a integração inversa. Por outro lado, se você mesclar o código da ramificação PRINCIPAL com a ramificação DESENVOLVIMENTO, o processo é chamado de integração de avanço.

Branch principal
Para obter mais informações sobre como criar e mesclar ramificações de código, consulte a seguinte página do site do CodePlex: Guia de Branches do Team Foundation Server 2.0.

Ramificar e mesclar envolvem os seguintes princípios:

  1. Cada ramificação deve ter uma política definida sobre como integrar o código nessa ramificação. Por exemplo, na estrutura de ramificação da ilustração anterior, você pode atribuir um membro da equipe como proprietário e gerente da ramificação PRINCIPAL. Esse membro é responsável por executar a operação de ramificação inicial, integrar alterações da ramificação DESENVOLVIMENTO na ramificação PRINCIPAL de forma inversa, integrar as alterações da ramificação PRINCIPAL na ramificação DESENVOLVIMENTO de forma avançada. A integração de avanço é importante quando a ramificação PRINCIPAL também integra alterações de outras ramificações.

  2. A ramificação PRINCIPAL deve conter o código que passou nos testes de integração para que esteja sempre pronto para uma versão.

  3. A ramificação DESENVOLVIMENTO (ou trabalho) evolui constantemente porque os membros da equipe fazem check-in de alterações periodicamente.

  4. Os rótulos são instantâneos dos arquivos em uma ramificação em um momento específico.

    Para obter mais informações, consulte Usar rótulos para obter um instantâneo de seus arquivos.

O Build do Team Foundation permite que você escolha entre vários tipos de compilações para suas ramificações: manual, contínua, restrita, progressiva e agendada. Recomendamos que a ramificação PRINCIPAL tenha um tipo de compilação de check-in restringido. Isso significa que a ramificação DESENVOLVIMENTO deve passar em todos os requisitos da ramificação PRINCIPAL antes que você possa confirmar uma integração inversa. A ramificação DESENVOLVIMENTO deve executar um tipo de compilação contínua porque sua equipe deve saber o mais rápido possível quando um novo check-in afeta a ramificação DESENVOLVIMENTO.

Com que frequência sua equipe faz a integração inversa e de avanço?

Conforme mostrado na ilustração, a integração inversa e de avanço deve ocorrer pelo menos quando você conclui uma história de usuário. Embora cada equipe possa definir a conclusão de forma diferente, a conclusão de uma história de usuário geralmente significa que você conclui a funcionalidade e os testes de unidade correspondentes. Você pode fazer a integração inversa na ramificação PRINCIPAL somente depois que os testes de unidade verificaram a estabilidade da ramificação DESENVOLVIMENTO.

Branch em dois sprints
Se você tiver mais de uma ramificação de trabalho (DESENVOLVIMENTO), a integração de avanço em todas as ramificações de trabalho deverá ocorrer assim que qualquer ramificação for integrada à ramificação PRINCIPAL. Como a ramificação PRINCIPAL é mantida estável, a integração antecipada é segura. Os conflitos ou falhas em ramificações de trabalho podem ocorrer porque você não pode garantir que as ramificações de trabalho sejam estáveis.

É importante que você resolva qualquer conflito o mais rápido possível. Usando um arquivo com check-in restringido na ramificação PRINCIPAL, você ajuda a tornar a integração inversa mais fácil porque as restrições de qualidade ajudam a evitar conflitos ou erros na ramificação PRINCIPAL. Para obter mais informações, consulte Fazer check-in em uma pasta controlada por um processo de build de check-in restrito.

Como sua equipe gerencia as fontes que implementam histórias de usuário diferentes?

Como a ilustração a seguir mostra, você pode fazer check-in das alterações em uma ramificação de trabalho periodicamente para concluir uma história de usuário. Você pode implementar histórias de vários usuários na mesma ramificação ao mesmo tempo. No entanto, você pode fazer a integração inversa na ramificação PRINCIPAL somente ao terminar todo o trabalho em andamento. É recomendado que você agrupe histórias de usuários por tamanho similar porque não é desejável ter uma histórica de usuário grande bloqueando a integração de histórias pequenas. Você pode dividir os dois conjuntos de histórias de usuários em duas ramificações.

Check-in Conclui o histórico do Usuário

Quando a equipe deve adicionar uma ramificação?

Você deve criar ramificações nas seguintes situações:

  • Quando você precisar liberar o código em uma agenda/um ciclo diferente das ramificações existentes.

  • Quando seu código exige uma política de ramificação diferente. Se você criar uma nova ramificação que tem a nova política, poderá adicionar o valor estratégico ao seu projeto.

  • Quando a funcionalidade é liberada a um cliente, e sua equipe planeja fazer as alterações que não afetam o ciclo planejado de liberação.

Você não deve criar uma ramificação para cada história de usuário porque cria um custo alto de integração. Embora o TFVC torne a ramificação fácil, a sobrecarga de gerenciar ramificações pode se tornar significativa se você tiver muitas ramificações.

Como a equipe gerencia liberações da perspectiva de controle de versão?

Sua equipe deve ser capaz de liberar o código no final de qualquer sprint. Usando o Team Foundation Server, você pode rotular uma ramificação para tirar um instantâneo do código em um momento específico. Como a ilustração a seguir mostra, você pode rotular a ramificação PRINCIPAL para uma versão. Isso permite retornar a ramificação ao seu estado nesse momento.

Rotular um branch para tirar um instantâneo do código
Como você deve implementar atualizações em versões, criar uma ramificação para uma versão ajuda sua equipe continuará a trabalhar independentemente no próximo sprint sem criar conflitos com versões futuras. A ilustração a seguir mostra uma ramificação que contém o código para uma atualização e que é integrado inversamente na ramificação PRINCIPAL após a liberação no final do segundo sprint.

Fazer a integração reversa de um branch que contém uma atualização
Quando você cria uma ramificação para uma versão, você deve criar essa ramificação na ramificação PRINCIPAL, que é a mais estável. Se você ramificar para a versão a partir de uma ramificação de trabalho, poderá dificultar a integração porque a estabilidade das ramificações de trabalho não é garantida.