A ճյուղեր հաջող մոդելին Git

Իմացեք, թե ինչպես օգտագործել Գիտ կարեւոր է, եւ սա ներառում է պահպանելով համատեղ զարգացման միջավայրի կառավարելի ծրագրային ապահովման.

Créditos

Este Post é uma versão em Português do original, em Inglês, “A successful Git branching model“, devidamente autorizado pelo autor, Vincent Driessen. Thank you man!

Por questões técnicas, algumas palavras-chaves foram propositalmente mantidas em inglês. Tentei garantir a originalidade do texto, mas confesso que precisei fazer ajustes para facilitar a compreensão em nosso idioma (PT-BR). Qualquer correção ou sugestão de melhoria na tradução é bem-vinda.

ներածություն

Este não é um Post ensinando a usar o Git. Se é isto que precisa, sugiro dar uma olhada no Manual do Git. Também não é nosso objetivo mostrar como se faz um versionamento de software, այս դեպքում, նայել Versionamento Semântico.

Aqui a proposta é gerenciar a colaboração da equipe no versionamento de software. Sabe quando você tem vários programadoresmexendoem um mesmo código-fonte? Isto é importante para agilizar o desenvolvimento, mas pode gerar imensa dor de cabeça (prejuízo e retrabalho) se não houver um controle. Para evitar que um desenvolvedor sobrescreva o trabalho de outro e garantir um desenvolvimento progressivo e organizado, minimizando os conflitos e gerenciando versões do software, é que utilizamos o Git e o modelo de branches հետեւել.

Modelo de branches

Neste post apresento o modelo de desenvolvimento que utilizei em alguns dos meus projetos (tanto no trabalho quanto particular) cerca de 1 anos atrás, e que tem sido muito bem-sucedido. Faz tempo eu queria escrever sobre isso, mas nunca encontrava um horário disponível, até agora. Não vou falar sobre detalhes de projeto, apenas sobre estratégias de branches e gerenciamento de releases.

Este modelo foca exclusivamente no Git como ferramenta para versionamento de todo nosso código-fonte. (A propósito, se você está interessado no Git, nossa empresa GitPrime fornece, իրական ժամանակի, algumas incríveis análises de dados para otimização da engenharia de software)

Por que git?

Para uma minuciosa discussão sobre os prós e contras do Git comparado aos sistemas de controles de código-fonte centralizado, նայել ա web. Há uma tremendaguerraem torno disso. Como desenvolvedor, prefiro o Git em relação a todas outras ferramentas existentes hoje. O Git sem dúvida mudou a forma dos desenvolvedores pensarem em fazer um միաձուլել ou criar uma մասնաճյուղ. Eu venho do clássico mundo do CVS/Subversion, onde merging/branching é algo que você só faz de vez em quando e sempre parece um pouco assustador (“Cuidado com os conflitos de միաձուլել, eles te mordem!”).

Já com o Git estas ações [merging/branching] são extremamente simples e representam uma das principais partes da nossa rotina de trabalho, acredite. օրինակ, no livro CSV/Subversion, branching ե merging são abordados pela primeira vez apenas nos capítulos posteriores (para usuários avançados), enquanto em qualquer livro sobre Git, isso é visto no capítulo 3 (básico).

Como consequência de sua simplicidade e natureza repetitiva, branching ե merging não são mais algo para se ter receio. Na verdade, as ferramentas de controle de versão deveriam ajudar a fazerմիաձուլել e criar մասնաճյուղ mais do que qualquer outra coisa.

Chega de conversa, vamos ao modelo de desenvolvimento. O modelo que irei apresentar aqui é essencialmente nada mais que um conjunto de procedimentos que cada membro da equipe deve seguir a fim de chegar a um processo de desenvolvimento de software gerenciado.

Descentralizado, mas centralizado

A configuração do repositório que utilizamos e que funciona muito bem com este modelo de branching é composta por um repositório central. Note que este repositório é apenastido comocentral (pois o Git é um DVCS [Distributed Version Control Systems], այլ կերպ ասած, não existe nada tal como um repositório central a nível técnico). Nós iremos referenciar este repositório como origin, uma vez que este nome é familiar a todos os usuários Git.

Cada desenvolvedor faz pulls ե pushes para o origin. Mas além da relação push-pull para o centralizado [origin], cada desenvolvedor pode também pegar [pull] as mudanças de outros pares para formar subequipes. օրինակ, isto pode ser útil para trabalhar junto com dois ou mais desenvolvedores em uma nova grande funcionalidade, previamente enviando [pushing] o trabalho em progresso para o origin. Na figura acima, existem as subequipes de Alice e Bob, Alice e David, e Clair and David.

Tecnicamente, isto significa nada mais que Alice definiu um Git remoto chamado Bob, apontando para o repositório de Bob, e vice-versa.

As principais branches

No fundo, este modelo de desenvolvimento é bastante inspirado por modelos existentes por aí. O repositório central possui dois ramos [branches] principais com uma vida infinita:

  • վարպետ
  • զարգանալ

The branch master մեջ origin deve ser familiar a todo usuário Git. Paralelo a branch master, existe um outro մասնաճյուղ chamado զարգանալ.

Consideramos origin/master como sendo o branch principal onde o código fonte de HEAD sempre reflete um estado production-ready [pronto para produção].

Consideramos origin/develop como sendo o մասնաճյուղ principal onde o código fonte de HEAD sempre reflete um estado com as mais recentes mudanças de desenvolvimento a serem entregues na próxima versão. Alguns chamariam isso deմասնաճյուղ de integração”. Aí é onde as mais sinistras construções acontecem.

Quando o código fonte no branch develop alcança um ponto estável e está pronto para ser lançado [released], todas as mudanças devem ser mescladas [merged] de volta para o branch master e depois marcados com um número de versão [ազատում]. Como isso é feito em detalhes, será discutido mais adiante.

ուստի, cada vez que as alterações são incorporadas [merged] de volta ao վարպետ, é gerada uma nova versão [released], por definição. Nós procuramos ser bastante rigorosos nisso, ապա, teoricamente, poderíamos até usar um script hook do Git para criar e enviar automaticamente nossa aplicação para os servidores de produção sempre que houver um commit no վարպետ.

Branches auxiliares

Ao lado das branches principais, վարպետ ե զարգանալ, nosso modelo de desenvolvimento usa uma variedade de branches de apoio para auxiliar o desenvolvimento simultâneo entre os integrantes da equipe, o que 1) facilita o rastreamento de novas funcionalidades [features], 2) prepara para entrega de uma nova versão [ազատում] ե 3) ajuda a rapidamente corrigir falhas em produção [hotfix]. Diferentemente dos branches principais, estes branches tem um tempo de vida curto, já que eventualmente serão removidos.

Os diferentes tipos de branches [auxiliares] que podemos usar, նրանք են:

  • Feature branches
  • Release branches
  • Hotfix branches

Cada um desses branches tem um propósito específico e está vinculado à regras rígidas, de modo que, branches podem dar origem a մասնաճյուղ e que branches devem ser mesclados [merged] a seus alvos. Nós veremos cada um deles [branches] em um instante.

Sob uma perspectiva técnica, esses branches não são consideradosespeciais”. Cada tipo de մասնաճյուղ é categorizado pela forma como os usamos. վերջ ի վերջո, são apenas simples branches do velho e bom Git.

Feature branches

[Features = recursos/funcionalidades]

Pode se ramificar [մասնաճյուղ] a partir de:
զարգանալ
Deve mesclar-se [միաձուլել] novamente a:
զարգանալ
Convenção de nomeação do մասնաճյուղ:
ամեն ինչ, exceto վարպետ, զարգանալ, release-*, or hotfix-*

Os feature branches (ou às vezes chamados de topic branches) são usados para desenvolver novos recursos/funcionalidades para uma versão próxima ou futura. Ao iniciar o desenvolvimento de uma feature, a versão alvo em que esse recurso será incorporado pode muito bem ser desconhecida nesse ponto.

A essência de um feature branches é que ele existe enquanto a feature estiver em desenvolvimento, mas eventualmente será incorporado [merged] de volta ao զարգանալ (para adicionar definitivamente a nova feature ao próximo ազատում) ou descartado (no caso de uma experiência mal sucedida).

Feature branches tipicamente existem apenas no repositório զարգանալ, não em origin.

Criando uma feature branches

$ git checkout -b myfeature develop
# Switched to a new branch "myfeature"

Incorporando uma feature finalizada no develop

Features finalizadas podem ser mescladas[merged] com a branch develop para adicioná-las definitivamente ao próximo ազատում.

$ git checkout develop
# Switched to branch 'develop'
$ git merge --no-ff myfeature
# Updating ea1b82a..05e9557
# (Summary of changes)
# $ git branch -d myfeature
# Deleted branch myfeature (was 05e9557).
$ git push origin develop

A flag no-ff faz com que a mesclagem [միաձուլել] sempre crie um novo objeto de commit, ainda que a mesclagem pudesse ser executada com um fast-forward [ff]. Isso evita que se perca informações sobre o histórico da existência de uma feature branch, agrupando todos os commits que foram adicionados à feature. Compare:

No último caso [da figura acima], é impossível ver a partir do histórico do Git quais dos commits foram implementados dentro de uma feature; você teria que ler manualmente todas as mensagens de log. Reverter uma feature inteira (այլ կերպ ասած, um grupo de commits), é uma verdadeira dor de cabeça na última situação, enquanto que é facilmente feito se a flag no-ff tiver sido usada.

sim, isso criará mais alguns objetos de commits (vazios), mas o ganho é muito maior do que o custo.

Release branches

[Release = lançamento/entrega/versão]

Pode se ramificar [մասնաճյուղ] a partir de:
զարգանալ
Deve mesclar-se [միաձուլել] novamente a:
զարգանալ ե վարպետ
Convenção de nomeação do մասնաճյուղ:
release-*

Os releases branches ajudam na preparação de uma nova versão de produção [production release]. Eles permitem colocar os pingos nos i’s de última hora. Além disso, eles permitem pequenas correções de bugs e definição de meta-dados para uma ազատում (número de versão, datas de compilação, եւ այլն). Ao fazer todo esse trabalho em um release branch, որ develop branch fica limpo para receber features da próxima grande ազատում [versão].

O momento chave para se criar uma nova release branch ramificando de զարգանալ é quando o զարգանալ já está (համարյա) refletindo o estado desejado da nova ազատում [versão]. Todas as features candidatas ao ազատում a ser construído devem ser incorporados [միաձուլել] դեպի զարգանալ neste momento. Já os features voltados para releases futuros devem esperar uma próxima ազատում [versão].

É exatamente no início de um release branch que o próximo ազատում recebe um número de versãonão antes. Até esse momento, որ develop branch refletiu alterações para onext release” [próxima versão], mas não está claro se essapróxima versãoacabará por ser 0.3 կամ 1.0, até que o release branch seja iniciado. Essa decisão é tomada no início do release branch e é realizada pelas regras do projeto sobre versionamento [sugiro ver sobreVersionamento Semântico“].

Criando um release branch

Os releases branches são criados a partir do develop branch. օրինակ, digamos que a versão 1.1.5 é a atual versão de produção e temos uma grande ազատում chegando. O estado de զարգանալ está pronto para apróxima versão” [next release] e decidimos que isso se tornaria a versão 1.2 (em vez de 1.1.6 կամ 2.0). ապա, nós nos ramificamos e damos ao release branch um nome refletindo o novo número de versão:

$ git checkout -b release-1.2 զարգանալ
# Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
# Files modified successfully, version bumped to 1.2.
$ git commit -ա -m "Bumped version number to 1.2"
# [release-1.2 74d9424] Bumped version number to 1.2
# 1 files changed, 1 insertions(+), 1 deletions(-)

Depois de criar um novo մասնաճյուղ e acessá-lo, nos esbarramos no número da versão. Aqui, bump-version.sh é um script shell que altera alguns arquivos da cópia de trabalho para refletir a nova versão. (Isso pode, պարզ, ser uma mudança manualo ponto é que alguns arquivos mudam.) ապա, é feito o commit do número da versão modificada.

Este novo մասնաճյուղ pode existir lá por um tempo, até que a ազատում seja lançada definitivamente. Durante esse período, correções de erros podem ser aplicadas neste մասնաճյուղ (em vez do develop branch). A adição de novos e grandes features aqui é estritamente proibida. Eles devem ser mesclados [merged] մեջ զարգանալ ե, այնքան, aguardar o próximo grande ազատում.

Finalizando um release branch

Quando o release branch está pronto para se tornar uma versão real, algumas ações precisam ser realizadas. Primeiro, որ release branch é mesclado em վարպետ (uma vez que cada commit no վարպետ é uma nova versão por definição, lembre-se). Em seguida, esse commit no վարպետ deve ser marcado para facilitar uma futura referência a este histórico de versões. վերջապես, as mudanças feitas no release branch precisam ser mescladas [merged] novamente para զարգանալ, de modo que os releases futuros também contenham essas correções de bugs.

As duas primeiras etapas no Git:

$ git checkout master
# Switched to branch 'master'
$ git merge --no-ff release-1.2
# Merge made by recursive.
# (Summary of changes)
$ git tag -ա 1.2

The ազատում agora está concluído e marcado para futura referência.

դիտողություն: você também pode usar as flags -s ou -u para assinar sua tag criptograficamente.

Para manter as mudanças feitas no release branch, precisamos juntá-las de volta ao զարգանալ. No Git:

$ git checkout develop
# Switched to branch 'develop'
$ git merge --no-ff release-1.2
# Merge made by recursive.
# (Summary of changes)

Este passo pode levar a um conflito de mesclagem (provavelmente vá, uma vez que mudamos o número da versão). Em caso afirmativo, conserte e faça o commit.

այժմ, que realmente terminamos, որ release branch pode ser removido, já que não precisaremos mais dele:

$ git branch -d release-1.2
# Deleted branch release-1.2 (was ff452fe).

Hotfix branches

Pode se ramificar [մասնաճյուղ] a partir de:
վարպետ
Deve mesclar-se [միաձուլել] novamente a:
զարգանալ ե վարպետ
Convenção de nomeação do մասնաճյուղ:
hotfix-*

Os Hotfix branches são muito parecidos com os release branches, pois eles também se destinam a preparar uma nova versão de produção, embora não planejada. Eles surgem da necessidade de agir imediatamente após um estado não desejado de uma versão de produção [em uso]. Quando ocorre um erro crítico em uma versão de produção, deve ser resolvido imediatamente, então um hotfix branch pode ser derivado da tag que marca a versão de produção existente no master branch.

A essência é que o trabalho dos membros da equipe (no develop branch) pode continuar, enquanto outra pessoa está preparando uma rápida correção da falha em produção.

Criando o hotfix branch

Os hotfix branches são criados a partir do master branch. օրինակ, supondo que a versão 1.2 é a versão atual da release de produção rodando e apresenta problemas devido a um erro grave. Mudanças no զարգանալ deixam o ainda instável. Nós podemos então ramificar um hotfix branch e começar a solucionar o problema:

$ git checkout -b hotfix-1.2.1 վարպետ
# Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
# Files modified successfully, version bumped to 1.2.1.
$ git commit -ա -m "Bumped version number to 1.2.1"
# [hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
# 1 files changed, 1 insertions(+), 1 deletions(-)

Não esqueça de trocar o número da versão após a ramificação!

Em seguida, corrija o erro e faça o commit da correção em um ou mais commit separados.

$ git commit -m "Fixed severe production problem"
# [hotfix-1.2.1 abbe5d6] Fixed severe production problem
# 5 files changed, 32 insertions(+), 17 deletions(-)

Finalizando um hotfix branch

Quando terminado, որ bugfix precisa ser mesclado de volta ao վարպետ, mas também precisa ser incorporado novamente para զարգանալ, a fim de garantir que o bugfix também esteja incluído na próxima versão. Isso é bastante semelhante ao modo como as release branches são finalizadas.

Primeiro, atualize o վարպետ e tag a ազատում [marque a verão]:

$ git checkout master
# Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
# Merge made by recursive.
# (Summary of changes)
$ git tag -ա 1.2.1

դիտողություն: você também pode usar as flags -s ou -u para assinar sua tag criptograficamente.

Em seguida, inclua o bugfix no զարգանալ também:

$ git checkout develop
# Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
# Merge made by recursive.
# (Summary of changes)

A única exceção à regra aqui é que, quando existir um release branch em andamento, as mudanças de hotfix precisam ser mescladas para esse release branch, ao invés de զարգանալ. Mesclar o bugfix no release branch irá fazer com que o bugfix seja mesclado no զարգանալ também, quando o release branch for concluído. (Se o trabalho no զարգանալ requer imediatamente esse bugfix e não puder esperar até que o release branch seja concluído, você pode seguramente mesclar o bugfix համար deveolp também.)

վերջապես, remova a մասնաճյուղ temporária:

$ git branch -d hotfix-1.2.1
# Deleted branch hotfix-1.2.1 (was abbe5d6).

Resumo

Embora não haja nada realmente extraordinário neste modelo de ramificação, a figura no início do Post pode ser muito útil em nossos projetos. Ela mostra um modelo mental fácil de compreender e permite aos membros da equipe desenvolver um entendimento comum dos processos de branching ե releasing.

Uma versão em PDF de alta qualidade da figura é fornecida no blog do post original: http://nvie.com/posts/a-successful-git-branching-model/ [ou no link de Download abaixo]. Vá em frente e coloque-o na parede para obter uma rápida referência a qualquer momento.

Ընդամենը մուտքերը: 8863

A ակնարկ է “A ճյուղեր հաջող մոդելին Git

Թողնել Պատասխանել

Ձեր էլ. Փոստի հասցեն չի հրապարակվելու. Պահանջվող դաշտերը նշված են *