Causar danos inadvertidamente com o Git pode ser muito fácil. Ainda assim, a melhor maneira de usar Ir sempre será controverso.
Isso porque o próprio Git apenas detalha as operações básicas de ramificação, o que deixa seus padrões de uso - ou seja, modelos de ramificação - uma questão de opinião do usuário. Os modelos de ramificação Git prometem aliviar a dor, organizando o caos que inevitavelmente surge quando os desenvolvedores de software fazem alterações em suas bases de código.
Como muitos desenvolvedores, você queria algo que “simplesmente funcionasse” para que pudesse continuar com o desenvolvimento de software real. Então você pegou Fluxo Git , um modelo de ramificação frequentemente recomendado para usuários Git. Talvez você tenha concordado com a lógica do fluxo do Git no início, até que encontrou alguns empecilhos na prática. Ou talvez o fluxo do Git não pareça um ajuste bom o suficiente para você adotá-lo. Afinal, existem inúmeras variáveis em jogo e nenhum modelo de ramificação único funcionará bem em todas as situações.
Boas notícias! Uma variação do modelo de fluxo clássico do Git, fluxo Git aprimorado simplifica as manobras mais comuns do fluxo de trabalho do Git e ainda mantém as vantagens principais.
Sou um forte defensor do fluxo Git desde que descobri como ele se destaca no desenvolvimento de um produto que evolui em incrementos de valor significativo (Em outras palavras, lançamentos )
Um incremento de valor significativo requer uma quantidade significativa de tempo para ser concluído, como os sprints de mais de duas semanas normalmente usados em Scrum baseado no desenvolvimento. Se uma equipe de desenvolvimento já implementou a produção, pode haver problemas se o escopo da próxima versão se acumular no mesmo lugar onde reside o código de produção - por exemplo, no branch principal do repositório Git que eles usam.
Enquanto o produto ainda está na fase inicial de desenvolvimento, ou seja, não há produção e não há usuários reais do produto, está tudo bem para a equipe simplesmente manter tudo dentro do ramo principal. Na verdade, é mais do que bom: essa estratégia permite o ritmo de desenvolvimento mais rápido sem muita cerimônia. Mas as coisas mudam em um ambiente de produção; então, pessoas reais começam a confiar que o produto seja estável.
Por exemplo, se houver um bug crítico na produção que precisa ser corrigido imediatamente, seria um grande desastre para a equipe de desenvolvimento ter que reverter todo o trabalho acumulado no branch principal até agora apenas para implantar a correção. E implantar código sem o teste adequado - seja o código considerado incompleto ou bem desenvolvido - claramente não é uma opção.
É aí que os modelos de ramificação brilham, incluindo o fluxo Git. Qualquer modelo sofisticado de ramificação deve responder a perguntas sobre como isolar o próximo lançamento da versão do sistema usado atualmente pelas pessoas, como atualizar essa versão com o próximo lançamento e como introduzir hotfixes de quaisquer bugs críticos para a versão atual.
O processo de fluxo do Git aborda esses cenários fundamentais separando “principal” (o ramo de produção ou “versão atual”) e “desenvolver” (o ramo de desenvolvimento ou “próximo lançamento”) e fornecendo todas as regras sobre o uso de ramos de recurso / lançamento / hotfix . Ele resolve com eficácia muitas dores de cabeça dos fluxos de trabalho de desenvolvimento de produtos baseados em lançamento.
Mas mesmo com projetos bem adequados ao modelo de fluxo clássico do Git, sofri os problemas típicos que ele pode trazer:
A primeira vez que usei o fluxo Git aprimorado foi em um projeto greenfield de código fechado. Eu estava trabalhando com outro desenvolvedor e estávamos trabalhando no projeto nos comprometendo diretamente com o branch principal.
Observação: até o primeiro lançamento público de um produto, faz sentido comprometer todas as alterações diretamente no branch principal - mesmo se você for um defensor do fluxo do Git - por causa da velocidade e simplicidade do fluxo de trabalho de desenvolvimento. Como ainda não há produção, não há possibilidade de um bug de produção que a equipe precise corrigir o mais rápido possível. Fazer toda a mágica de ramificação que o fluxo clássico do Git implica é, portanto, um exagero neste estágio.
Então chegamos perto do lançamento inicial e concordamos que, além desse ponto, não estaríamos mais confortáveis em nos comprometermos diretamente com o branch principal. Tínhamos mudado muito rapidamente e as prioridades de negócios não deixavam muito espaço para estabelecer um processo de desenvolvimento sólido, ou seja, um com testes automatizados suficientes para nos dar a confiança de que nosso branch principal estava pronto para o lançamento.
Parecia ser um caso válido para o modelo de fluxo clássico do Git. Com ramificações principais e de desenvolvimento separadas e tempo suficiente entre incrementos de valor significativos, havia confiança de que o controle de qualidade manual produziria resultados bons o suficiente. Quando defendi o fluxo do Git, meu colega sugeriu algo semelhante, mas com algumas diferenças importantes.
No começo, eu empurrei de volta. Pareceu-me que alguns dos “patches” propostos para o fluxo clássico do Git eram um pouco revolucionários demais. Achei que eles poderiam quebrar a ideia principal, e toda a abordagem seria insuficiente. Mas, pensando melhor, percebi que esses ajustes não interrompem o fluxo do Git. Enquanto isso, eles o tornam um modelo de ramificação Git melhor resolvendo todos os pontos problemáticos mencionados acima.
Após o sucesso com a abordagem modificada naquele projeto, eu usei em outro projeto de código fechado com uma pequena equipe por trás dele, onde eu era o proprietário permanente da base de código e um desenvolvedor terceirizado ou dois ajudavam de tempos em tempos. Neste projeto, entramos em produção há seis meses e, desde então, temos usado testes de CI e E2E por mais de um ano, com lançamentos a cada mês ou mais.
Minha experiência geral com essa nova abordagem de ramificação foi tão positiva que eu queria compartilhá-la com meus colegas desenvolvedores para ajudá-los a contornar as desvantagens do fluxo Git clássico.
Para o isolamento do trabalho no fluxo Git aprimorado, ainda existem dois ramos de longa duração, principal e desenvolver. (Os usuários ainda têm recursos de hotfix e lançamento - com ênfase em 'recursos', uma vez que esses não são mais branches. Entraremos em detalhes na seção de diferenças.)
Não há um esquema de nomenclatura oficial para branches de recursos de fluxo clássicos do Git. Basta ramificar a partir do desenvolvimento e fundir novamente para desenvolver quando o recurso estiver pronto. As equipes podem usar qualquer convenção de nomenclatura que desejarem ou simplesmente esperar que os desenvolvedores usem nomes mais descritivos do que 'meu-branch'. O mesmo é verdadeiro para o fluxo Git aprimorado.
Todos os recursos acumulados na ramificação de desenvolvimento até algum ponto de corte irão moldar a nova versão.
Eu recomendo fortemente o uso de squash merge para ramificações de recursos para manter o histórico bom e linear na maioria das vezes. Sem isso, os gráficos de commit (das ferramentas GUI ou git log --graph
) começam a parecer desleixados quando uma equipe está lidando com até mesmo um punhado de branches de recursos:
Mas mesmo que você esteja bem com o visual neste cenário, há outro motivo para reprimir. Sem comprimir, commitar visualizações de histórico — entre elas planas git log
(sem --graph
) e também GitHub - conte histórias um tanto incoerentes, mesmo com o mais simples dos cenários de mesclagem:
A advertência ao usar a mesclagem de squash é que o histórico de ramificações do recurso original é perdido. Mas essa advertência nem mesmo se aplica se você estiver usando o GitHub, por exemplo, que expõe toda a história original de um branch de recurso por meio da solicitação pull que foi mesclada, mesmo após o branch de recurso em si ser excluído.
Vamos passar pelo ciclo de lançamento, pois (espero) é a coisa principal que você fará. Quando chegarmos ao ponto em que gostaríamos de liberar o que foi acumulado no desenvolvimento, é estritamente um superconjunto do principal. Depois disso, é onde começam as maiores diferenças entre o fluxo Git clássico e aprimorado.
Cada etapa para fazer uma versão com fluxo Git aprimorado difere do processo de fluxo Git clássico:
git push origin
.git push --force
, já que o repo remoto não aceitará uma 'mudança drástica' tão facilmente. Novamente, isso não é tão inseguro quanto pode parecer neste contexto porque:Os casos de Hotfix são duplos. Se você estiver fazendo um hotfix quando não há liberação ativa —Ou seja, a equipe está preparando uma nova versão no branch de desenvolvimento — é uma brisa: comprometa-se com a principal, faça com que suas mudanças sejam implantadas e testadas na preparação até que estejam prontas e, em seguida, implante para produção.
Como última etapa, selecione seu commit do main para o desenvolvimento para garantir que a próxima versão conterá todas as correções. Caso você termine com vários commits de hotfix, você economiza esforços - especialmente se seu IDE ou outra ferramenta Git puder facilitar isso - criando e aplicando um patch em vez de selecionar várias vezes. Tentar esmagar o merge main para desenvolver após o lançamento inicial provavelmente resultará em conflitos com o progresso independente feito no branch de desenvolvimento, então eu não recomendo isso.
Lidando com hotfixes durante um lançamento ativo - ou seja, quando você apenas força o pressionamento principal e ainda está preparando a nova versão - é a parte mais fraca do fluxo Git aprimorado. Dependendo da duração do seu ciclo de lançamento e da gravidade do problema que você precisa resolver, sempre tente incluir correções na própria versão - essa é a maneira mais fácil de fazer e não interromperá o fluxo de trabalho geral.
Caso isso seja impossível - você tem que introduzir uma correção rapidamente e não pode esperar que a nova versão fique pronta - então prepare-se para um procedimento Git um tanto intrincado:
Com planejamento adequado, qualidade de código alta o suficiente e um desenvolvimento saudável e cultura de controle de qualidade, é improvável que sua equipe precise usar este método. Foi prudente desenvolver e testar esse plano de desastre para o fluxo Git aprimorado, apenas para garantir, mas nunca precisei usá-lo na prática.
Nem todo projeto requer um ambiente de desenvolvimento dedicado. Pode ser fácil configurar um ambiente de desenvolvimento local sofisticado em cada máquina de desenvolvedor.
Mas um ambiente de desenvolvimento dedicado pode contribuir para uma cultura de desenvolvimento mais saudável. Executar testes, medir a cobertura de teste e calcular métricas de complexidade no ramo de desenvolvimento geralmente diminui o custo dos erros, detectando-os bem antes que terminem no teste.
Descobri que alguns padrões de CI / CD são especialmente úteis quando combinados com o fluxo Git aprimorado:
Esses padrões são relativamente simples, mas fornecem um maquinário poderoso para dar suporte às operações de desenvolvimento do dia a dia.
O fluxo Git aprimorado não é para todos. Ele aproveita a controvertida tática da força empurrando o ramo principal, então os puristas podem se ressentir disso. De um ponto de vista prático, não há nada de errado com isso.
Conforme mencionado, os hotfixes são mais desafiadores durante o lançamento, mas ainda são possíveis. Com a devida atenção ao controle de qualidade, cobertura de teste, etc., que não deve acontecer com muita frequência, então, da minha perspectiva, é uma troca válida para os benefícios gerais do fluxo Git aprimorado em comparação ao fluxo Git clássico. Eu estaria muito interessado em ouvir como o fluxo aprimorado do Git se sai em equipes maiores e com projetos mais complexos, onde os hotfixes podem ser uma ocorrência mais frequente.
Minha experiência positiva com o modelo de fluxo Git aprimorado também gira principalmente em torno de projetos comerciais de código fechado. Pode ser problemático para um projeto de código-fonte aberto em que as solicitações pull são frequentemente baseadas em uma derivação de versão antiga da árvore de código-fonte. Não há obstáculos técnicos para resolver isso - pode exigir mais esforço do que o esperado. Agradeço o feedback de leitores com muita experiência no espaço de código aberto com relação à aplicabilidade do fluxo Git aprimorado em tais casos.
Agradecimentos especiais ao colega ApeeScape Antoine Pham por seu papel principal no desenvolvimento da ideia por trás do fluxo Git aprimorado.
Como um Microsoft Gold Partner , ApeeScape é sua rede de elite de especialistas da Microsoft. Monte equipes de alto desempenho com os especialistas de que você precisa - em qualquer lugar e exatamente quando você precisar deles!
O fluxo Git é um modelo de ramificação para o sistema de controle de versão Git (VCS). Um modelo de ramificação baseia-se em operações básicas do Git, prescrevendo padrões de uso destinados a permitir o gerenciamento robusto de versões. O fluxo do Git foi anunciado publicamente em um artigo de blog de Vincent Driessen em 2010 e permaneceu popular desde então.
A estratégia de ramificação de fluxo Git é excelente ao desenvolver um produto que evolui em incrementos de valor significativos. Ele faz isso separando 'principal' (o ramo de produção ou 'versão atual') e 'desenvolver' (o ramo de desenvolvimento ou 'próximo lançamento') e fornecendo todas as regras necessárias sobre o uso de ramos auxiliares.
Você usa o fluxo Git seguindo seu padrão prescrito. Isso permite que sua equipe obtenha respostas a perguntas sobre como isolar a próxima versão da versão do sistema atualmente em produção, como atualizar essa versão com a próxima versão e como introduzir hotfixes de quaisquer bugs críticos para a versão atual.
Se você deve usar o fluxo Git ou não, depende do seu projeto específico. A principal pergunta a ser respondida é: 'O fluxo de trabalho de desenvolvimento geral tem garantia de qualidade automática suficiente para manter o branch principal no estado de liberação?' Se a resposta for não, esse projeto provavelmente se beneficiará do fluxo do Git.
Não existe um único fluxo de trabalho Git melhor, porque a resposta depende do contexto específico do projeto. Alguns projetos se beneficiarão do fluxo do Git ou de uma variação dele, enquanto outros serão melhores com uma abordagem de desenvolvimento baseada em tronco.