O Git pode dar suporte ao seu projeto não apenas com controle de versão, mas também com colaboração e gerenciamento de lançamento. Entender como os padrões de fluxo de trabalho do Git podem ajudar ou atrapalhar um projeto lhe dará o conhecimento para avaliar e adaptar os processos Git do seu projeto de forma eficaz.
Ao longo deste guia, isolarei os padrões de processo de desenvolvimento de software encontrados em fluxos de trabalho Git comuns. O conhecimento deles o ajudará a encontrar uma direção ao ingressar, criar ou desenvolver um equipe de desenvolvimento . Os prós e contras de certos tipos de projetos ou equipes serão destacados nos exemplos de fluxo de trabalho que exploramos, para que você possa escolher o que pode funcionar bem para o seu cenário.
Esta não é uma introdução ao uso do Git. tem guias fabulosos e documentação para isso já está lá fora. Você se beneficiará com este guia de fluxo de trabalho Git se já tiver experiência em uma equipe de desenvolvimento de aplicativos e enfrentou obstáculos no fluxo de trabalho, implosões de integração ou git-tastrophes - esses padrões podem lançar alguma luz sobre como evitar essas situações no futuro.
Em termos de processo Git, a colaboração geralmente envolve fluxos de trabalho ramificados. Pensar no futuro sobre como entrelaçar árvores de commit ajudará a minimizar bugs de integração e apoiar sua estratégia de gerenciamento de versão.
Use um ramo de integração com equipes de desenvolvimento de software que trabalham para implantar uma coleção de contribuições na produção como uma entidade única. Isso se opõe às equipes que se concentram na implantação de recursos individualmente. Muitas vezes as equipes podem querer fazer o último, mas limitações práticas impõem um processo que agrupa seus esforços, e a equipe acaba fazendo o primeiro, então certifique-se de revisar seu uso real do Git para ver se você se beneficiaria com o uso deste tipo de colaboração padronizar.
Este padrão de fluxo de trabalho é um ponto de teste útil para quando o risco de integrar várias ramificações é alto o suficiente para garantir o teste das contribuições combinadas como um todo.
Uma ramificação de integração geralmente consiste em um recurso principal e várias contribuições menores a serem implementadas juntas. Coloque uma ramificação de integração no processo de sua equipe de desenvolvimento (perguntas e respostas e testes de aceitação, por exemplo). Envie commits menores para ele para deixá-lo pronto para produção e, em seguida, use um branch de ambiente ou um branch de lançamento (discutido abaixo) para prepará-lo para implantação.
Esteja ciente de que as contribuições na ramificação de integração precisam ser mescladas no próximo estágio de liberação antes que outro recurso principal possa ser mesclado na ramificação de integração - caso contrário, você estará combinando recursos em diferentes estágios de conclusão. Isso inibirá sua capacidade de liberar o que está pronto.
As equipes vão querer usar ramos de tópico se for importante manter suas árvores de commit em um estado que possa ser facilmente lido ou ter recursos individuais revertidos. Ramificações de tópico significam que os commits podem ser sobrescritos (usando um push forçado) para limpar sua estrutura e serem reduzidos a um commit de recurso.
As ramificações de tópicos geralmente são propriedade de um colaborador individual, mas também podem ser um espaço designado para uma equipe desenvolver um recurso. Outros contribuidores sabem que este tipo de branch pode ter sua árvore de commit reescrita a qualquer momento, e não devem tentar manter seus branches locais sincronizados com ele.
Sem utilizar branches de tópico em seu fluxo de trabalho Git, você está restrito a seguir os commits que envia para um branch remoto. Forçar o envio de uma nova árvore de commits para um branch remoto pode irritar outros contribuidores que confiam na integridade mantida do branch com o qual eles sincronizam.
Provavelmente, você já usa esse padrão de fluxo de trabalho sem perceber, mas vale a pena ter um conjunto compartilhado de definições entre as equipes para reforçar as práticas por trás delas. Por exemplo, você pode achar que a convenção de prefixar o nome do ramo com as iniciais do criador do ramo ajuda a sinalizar quais são os ramos do tópico. De qualquer forma, cabe a sua equipe decidir sobre as convenções internas.
NÃO usar branches de tópico em repositórios públicos, você causa uma miríade de conflitos para qualquer um que sincronizou seus branches locais com um branch de tópico que teve sua árvore de commit reescrita.
Os projetos de código aberto prosperam usando esse recurso originado do Github. o garfo capacita os mantenedores do repositório com um gateway forçado em vez de enviar diretamente para um branch de repositório de origem, mas o mais importante, facilita a colaboração. Wahoo!
Você pode se encontrar em um cenário em que a criação de um fork de um repositório privado também atenda às suas necessidades. Definir o repositório de origem como somente leitura para os contribuidores do repositório fork e rolar com solicitações pull oferece os mesmos benefícios que a experiência da comunidade de software livre. Equipes de diferentes organizações podem trabalhar de forma eficaz usando um fork que pode ser a plataforma para comunicação e adesão à política do projeto.
O padrão de fluxo de trabalho fork dá às equipes seu próprio espaço para trabalhar da maneira que estão acostumados com um único ponto de integração entre os dois repositórios - uma solicitação pull. A comunicação excessiva é imprescindível na descrição da solicitação pull. As equipes tiveram fluxos de comunicação separados antes de uma solicitação pull ser emitida, e destacar as decisões que já foram feitas irá acelerar o processo de revisão.
É claro que um benefício do fluxo de trabalho fork é que você pode direcionar comentários aos contribuidores do repositório de origem, conforme as permissões caem em cascata. Do ponto de vista do repositório de origem, você tem o controle para excluir os garfos quando eles não forem mais necessários.
Certifique-se de usar uma ferramenta que facilite a bifurcação e pull de solicitações para aproveitar esse padrão. Essas ferramentas não se limitam a Github : outras escolhas populares são Bitbucket e GitlLab . Mas existem alguns outros serviços de hospedagem de fluxo de trabalho Git que terão esses recursos (ou semelhantes). Escolha qual serviço funciona melhor para você.
NÃO use um fork de um repositório privado para cada membro de uma equipe. Os numerosos repositórios bifurcados podem dificultar a colaboração de vários membros no mesmo branch de recursos, e manter todos esses repositórios em sincronia pode tornar-se sujeito a erros devido ao grande número de peças móveis. Os projetos de código aberto têm membros da equipe central com acesso por push ao repositório de origem, o que diminui essa sobrecarga.
Uma estratégia comum de terceirização é ter “vagas” de contribuição em um projeto que pode ser preenchido por vários desenvolvedores de software. Cabe à empresa de terceirização gerenciar seu pipeline de recursos para entregar as horas contratadas. Os problemas que enfrentam são como integrar, treinar e manter um pool de seus desenvolvedores para os projetos de cada cliente.
Usando um clone do repositório do projeto estabelece um treinamento isolado e campo de comunicação para a equipe terceirizada gerenciar suas contribuições, aplicar políticas e aproveitar o compartilhamento de conhecimento - tudo sob o olhar atento da equipe de desenvolvimento do cliente. Uma vez que uma contribuição é considerada padrão e pronta para o repositório principal, ela pode ser enviada para uma das ramificações remotas do repositório de origem e integrada como de costume.
Alguns projetos têm grandes expectativas de seguir suas convenções de codificação e padrões de fluxo de trabalho Git definidos para contribuir com seu repositório. Pode ser difícil trabalhar neste ambiente até que você tenha aprendido o básico, então trabalhe junto como uma equipe para otimizar o tempo de ambas as partes.
NÃO criar uma cópia hospedada do repositório do cliente sem sua permissão, você pode estar quebrando um acordo contratual, verifique antecipadamente se esta prática beneficiará o projeto com o cliente.
As etapas entre a colaboração e o lançamento começarão em diferentes pontos do processo de desenvolvimento de cada equipe. Geralmente, você não gostaria de usar mais de um padrão Git de gerenciamento de versão. Você deseja ter o fluxo de trabalho mais simples possível, que permitirá que sua equipe forneça com eficácia.
Seu processo de desenvolvimento de software pode ser suportado por vários ambientes para ajudar na garantia de qualidade antes de ser implantado na produção. Ramos ambientais imitar os estágios desse processo: cada estágio corresponde a uma ramificação e as contribuições fluem por meio delas em um pipeline.
As equipes que executam esses processos geralmente têm ambientes de aplicativo configurados para cada estágio do pipeline, por exemplo, “QA”, “Staging” e “Production”. Nesses casos, a infraestrutura está pronta para dar suporte ao pessoal responsável por aprovar um recurso ou contribuição para sua fatia do que significa estar pronto para produção (por exemplo, teste exploratório, QA, teste de aceitação), antes de movê-lo para o próximo etapa. Isso dá a eles seu próprio local para implantar, testar e avaliar em relação aos seus requisitos, com um fluxo de trabalho Git para registrar sua jornada através do túnel de aprovação.
Ter uma ramificação para cada estágio do processo é OK para pequenas equipes que podem trabalhar para uma liberação como uma unidade. Infelizmente, um pipeline como esse pode facilmente obstruir ou acumular e deixar lacunas. Ele acopla seu processo Git à sua infraestrutura, o que pode causar problemas quando o recurso exige um aumento e ambos os processos precisam ser escalonados.
NÃO use este padrão sem considerar os benefícios de longo prazo de outros padrões primeiro.
Uma equipe que envia uma coleção de contribuições para seu aplicativo de produção como uma unidade em sprints sucessivos pode encontrar lançar ramos um ajuste favorável.
Uma coleção de commits quase “prontos para produção” recebe pequenas correções de bugs em um branch de lançamento. Use uma ramificação de integração para combinar e testar os recursos antes de mover sua árvore de commits para uma ramificação de lançamento. Limite a responsabilidade de um branch de lançamento para ser uma verificação final antes da implantação no aplicativo de produção.
As ramificações de lançamento diferem das ramificações de ambiente porque têm uma vida útil curta. Ramificações de lançamento são criadas somente quando necessário e destruídas após sua árvore de commits ter sido implantada na produção.
Tente evitar o acoplamento de ramificações de lançamento ao seu roteiro de desenvolvimento de software. Restringir-se a seguir um plano pré-determinado atrasa a implantação de uma versão até que todos os recursos planejados estejam prontos para produção. Não atribuir um número de versão ao roteiro antes de criar uma ramificação de lançamento pode aliviar esses tipos de atrasos, permitindo que os recursos que estão prontos para produção sejam colocados em uma ramificação de lançamento e implantados.
Use uma convenção de nomenclatura de número de versão para o nome do branch de lançamento para tornar óbvio qual versão do repositório foi implantada na produção.
Implante o branch master e não o branch de lançamento. Para encorajar a realização de pequenas correções em branches de lançamento antes de mesclar com o branch master, use um gancho Git no branch master para acionar após a fusão acontecer para implantar automaticamente a árvore de commit atualizada na produção.
Permitir que apenas um branch de lançamento exista em um determinado momento garante que você evitará a sobrecarga de manter vários branches de lançamento em sincronia uns com os outros.
NÃO use ramos de lançamento com várias equipes trabalhando no mesmo repositório. Mesmo que os branches de lançamento tenham vida curta, se a verificação final demorar muito, impedirá o outro time de lançar. Uma equipe pegando carona no branch de lançamento de outra equipe pode introduzir bugs e causar atrasos para ambas as equipes. Observe o padrão de lançamento com carimbo de data / hora abaixo, que funciona melhor para um número maior e grupos de colaboradores.
Os aplicativos com restrições de infraestrutura geralmente agendam suas implantações durante períodos de baixo tráfego. Se o seu projeto enfrenta filas regulares de recursos prontos para serem implantados, você pode se beneficiar do uso lançamentos com data e hora .
Uma liberação com carimbo de data / hora depende do processo de implantação para adicionar automaticamente uma marca de carimbo de data / hora ao último commit no branch master que foi implantado na produção. Os ramos de tópico são usados para colocar um recurso no processo de desenvolvimento antes de ser mesclado no ramo mestre para aguardar a implantação.
A marca de carimbo de data / hora deve incluir um carimbo de data / hora real e um rótulo para indicar que representa uma implantação, por exemplo: deployed-201402121345
.
Incluir metadados de implantação, na forma de marca de data e hora na árvore de commits do branch master, ajudará você a depurar regressões liberadas no aplicativo de produção. A pessoa encarregada de localizar a causa do problema provavelmente não sabe muito sobre cada linha implementada no aplicativo de produção. Executando um git diff
O comando nas duas últimas tags pode fornecer rapidamente um instantâneo de quais commits foram implantados pela última vez e quem são os autores dos commits que podem ajudar a resolver o problema.
Os ramos com carimbo de data / hora são mais do que parecem na superfície. Um mecanismo simples para registrar uma implantação de recursos enfileirados requer uma quantidade surpreendente de bons processos para conduzi-lo. O processo pode ser dimensionado e funciona bem com uma pequena equipe de colaboradores também.
Para que esse padrão de fluxo de trabalho Git seja realmente eficaz, é necessário que o branch master esteja sempre implementável. Isso pode significar coisas diferentes para sua equipe, mas essencialmente todos os commits devem ter passado pelo processo de desenvolvimento de seus projetos antes de terminar no branch master.
Novos commits no branch master acontecerão várias vezes ao dia. Este é um problema para branches de tópico que passaram pelo processo de desenvolvimento e não foram sincronizados com o branch master durante esse tempo. Infelizmente, tal cenário pode introduzir regressões no branch master quando os conflitos de mesclagem são tratados incorretamente.
Se conflitos de mesclagem surgirem entre um branch de tópico e o branch master, então o risco de introduzir um novo bug deve ser discutido com sua equipe antes de atualizar o branch master remoto. Se houver qualquer dúvida de que uma regressão poderia ocorrer, o ramo do tópico pode ser colocado de volta no processo de garantia de qualidade com os conflitos de mesclagem resolvidos.
Para reduzir bugs de integração, os desenvolvedores que estão trabalhando em partes relacionadas do repositório podem colaborar sobre quando é melhor mesclar e sincronizar seus branches de tópico com o branch master. Ramificações de integração funcionam bem para resolver conflitos de ramificações de tópicos relacionados também - elas devem ser submetidas ao processo de teste antes de serem mescladas na fila na ramificação mestre com implantação pendente.
Os projetos de desenvolvimento de software com muitos colaboradores precisam lidar com processos de gerenciamento de colaboração e lançamento com abordagens práticas e eficientes. Os metadados adicionais na árvore de commits que ganhamos com o uso de lançamentos com carimbo de data / hora são um indicador para a previsão das equipes que estão se preparando para responder aos problemas de produção.
Se você tem um repositório que não só executa na produção, mas também é usado por outros para seus próprios aplicativos hospedados, o uso de ramificações de versão pode dar à sua equipe a plataforma para oferecer suporte a usuários que não estão, ou não podem ficar na vanguarda dos desenvolvimentos de seu aplicativo .
Um repositório que usa ramificações de versão terá uma ramificação por versão secundária do aplicativo. Versões principais, secundárias e de patch são explicadas no Versão Semântica documentação. Ramificações de versão normalmente seguem uma convenção de nomenclatura para incluir a palavra 'estável' e remover o número do patch da versão do aplicativo: por exemplo, 2-3-stable
para tornar sua finalidade e confiabilidade óbvia para os usuários finais.
As tags Git podem ser aplicadas ao número da versão do patch do aplicativo, mas os ramos da versão não são tão refinados. Um branch de versão sempre apontará para o commit mais estável para uma versão secundária suportada.
Quando os patches de segurança ou a necessidade de funcionalidade de backport aparecerem, reúna os commits necessários para trabalhar com versões mais antigas do aplicativo que você suporta e envie-os para suas ramificações de versão, respectivamente.
NÃO use ramos de versão a menos que você suporte mais de uma versão de seu repositório.
Quando seu equipe muda de tamanho, ou seu projeto desenvolve seus processos através de avaliação contínua, não deixe de avaliar seu processo Git também. Use os padrões neste tutorial como um ponto de partida para ajudar a direcioná-lo no caminho da integridade do fluxo de trabalho Git.
O padrão neste guia pode ajudá-lo com alguma previsão na adaptação do seu sistema de controle de versão distribuído para trabalhar para você. Se você gostaria de ler sobre os fluxos de trabalho do Git, certifique-se de verificar Gitflow , Fluxo Github , e o mais importante, o incrível documentação git-scm !
Relacionado: Fluxo Git aprimorado explicado