
ક્રેડિટ
Este Post é uma versão em Português do original, ઇંગલિશ માં, “એક સફળ ગિટ ડાળીઓ મોડલ“, 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 programadores “mexendo” em 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) નજીક 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 tremenda “guerra” em 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, જ્યાં 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, માને. ઉદાહરણ માટે, 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 é apenas “tido como” central (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:
- માસ્ટર
- વિકાસ
આ 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, são:
- 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 considerados “especiais”. Cada tipo de શાખા é categorizado pela forma como os usamos. આખરે, são apenas simples branches do velho e bom Git.
Feature branches
– Pode se ramificar [શાખા] a partir de:
વિકાસ
– Deve mesclar-se [મર્જ] novamente a:
વિકાસ
– Convenção de nomeação do શાખા:
કંઈપણ, exceto માસ્ટર, વિકાસ, release-*, અથવા 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.
સિમ, isso criará mais alguns objetos de commits (vazios), mas o ganho é muito maior do que o custo.
Release branches
– 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 પ્રકાશન [આવૃત્તિ].
O momento chave para se criar uma nova release branch ramificando de વિકાસ é quando o વિકાસ já está (quase) refletindo o estado desejado da nova પ્રકાશન [આવૃત્તિ]. 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 પ્રકાશન [આવૃત્તિ].
É exatamente no início de um release branch que o próximo પ્રકાશન recebe um número de versão – não antes. Até esse momento, આ develop branch refletiu alterações para o “next release” [próxima versão], mas não está claro se essa “próxima versão” acabará 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 sobre “Versionamento 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 a “pró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-આવૃત્તિ.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 manual – o 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. Finalmente, 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 |
આ પ્રકાશન agora está concluído e marcado para futura referência.
ટીકા: você também pode usar as flags -s ou -u
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 [ઉપયોગ]. 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-આવૃત્તિ.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
Em seguida, inclua o bugfix no વિકાસ પણ:
$ 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 વિકાસ પણ, 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.)
Finalmente, remova a શાખા temporária:
$ git branch -d hotfix-1.2.1 # Deleted branch hotfix-1.2.1 (was abbe5d6). |
સારાંશ
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.

શુભ બપોર, sei que o Git foi desenvolvido inicialmente pelo sistema Linux mas ao se falar em portabilidade, gostaria de saber se o Git roda no windows MSIS e POSIX??