<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rodrigo Santana</title>
    <description>The latest articles on DEV Community by Rodrigo Santana (@rsantanarj).</description>
    <link>https://dev.to/rsantanarj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F757506%2Fe6ab7f9a-2300-4ef7-b419-91cfbc11b9e3.png</url>
      <title>DEV Community: Rodrigo Santana</title>
      <link>https://dev.to/rsantanarj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rsantanarj"/>
    <language>en</language>
    <item>
      <title>Gitflow: entenda quando e como você deve utilizar</title>
      <dc:creator>Rodrigo Santana</dc:creator>
      <pubDate>Sat, 05 Feb 2022 04:48:02 +0000</pubDate>
      <link>https://dev.to/rsantanarj/gitflow-entenda-quando-e-como-voce-deve-utilizar-398b</link>
      <guid>https://dev.to/rsantanarj/gitflow-entenda-quando-e-como-voce-deve-utilizar-398b</guid>
      <description>&lt;p&gt;Ao utilizar o Git para gerenciar versões de um projeto é preciso decidir o fluxo de trabalho (&lt;em&gt;workflow&lt;/em&gt;), que irá estabelecer funções bem específicas para diferentes &lt;em&gt;branches&lt;/em&gt; e definir quando e como elas devem interagir. Existem diversos fluxos de trabalho consolidados e que podem ser utilizados nos projetos. Neste artigo será abordado sobre o Gitflow, criado por Vincent Driessen.&lt;/p&gt;

&lt;p&gt;É comum as pessoas acharem que o Gitflow é um padrão que deve ser estabelecido em qualquer projeto que utilize Git, o que não é uma verdade. Não existe um fluxo de trabalho perfeito onde todos devam seguir, você deve decidir o modelo com base principalmente nas características de implantação do seu projeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como utilizar?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Branches&lt;/em&gt; básicas e de longa duração
&lt;/h3&gt;

&lt;p&gt;O Gitflow inicia com as seguintes &lt;em&gt;branches&lt;/em&gt; básicas&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Main&lt;/strong&gt; (antiga master): contém o código-fonte de produção&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Develop&lt;/strong&gt;: contém o código-fonte que irá integrar todas as alterações desenvolvidas para o ciclo do próximo lançamento&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Branches&lt;/em&gt; de suporte
&lt;/h3&gt;

&lt;p&gt;A partir das &lt;em&gt;branches&lt;/em&gt; básicas são criadas as &lt;em&gt;branches&lt;/em&gt; de suporte. Tais &lt;em&gt;branches&lt;/em&gt; podem ser do tipo &lt;em&gt;feature&lt;/em&gt;, &lt;em&gt;hotfix&lt;/em&gt; ou &lt;em&gt;release&lt;/em&gt;. A imagem abaixo, ilustra a origem para cada tipo de &lt;em&gt;branch&lt;/em&gt; e o destino. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fix9yx6y5jpcbq4lgnrdn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fix9yx6y5jpcbq4lgnrdn.png" alt="Gitflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Feature&lt;/strong&gt;: são ramos para desenvolvimento de &lt;strong&gt;novos recursos do sistema&lt;/strong&gt; ou &lt;strong&gt;correções de bugs não emergenciais&lt;/strong&gt;, criados a partir da &lt;em&gt;branch&lt;/em&gt; &lt;strong&gt;develop&lt;/strong&gt;. Após o desenvolvimento, as alterações são mescladas em direção a &lt;em&gt;branch&lt;/em&gt; &lt;strong&gt;develop&lt;/strong&gt; (origem).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hotfix&lt;/strong&gt;: são ramos para desenvolvimento de &lt;strong&gt;correções emergenciais&lt;/strong&gt;, criados a partir da &lt;em&gt;branch&lt;/em&gt; &lt;strong&gt;master&lt;/strong&gt;. Após o desenvolvimento, as alterações são mescladas em direção as &lt;em&gt;branches&lt;/em&gt; &lt;strong&gt;master&lt;/strong&gt; (origem) e &lt;strong&gt;develop&lt;/strong&gt;, para que a correção esteja disponível para as novas &lt;em&gt;features&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release&lt;/strong&gt;: são ramos utilizados para preparação do lançamento da próxima versão de produção. Nelas são permitidas alterações pontuais. Fazendo tais alterações na &lt;em&gt;release branch&lt;/em&gt;, a &lt;em&gt;branch&lt;/em&gt; develop fica livre para receber novos recursos da próxima versão. São criadas a partir da &lt;strong&gt;develop&lt;/strong&gt; e, após a validação da release, devem ser mescladas em direção a &lt;strong&gt;develop&lt;/strong&gt; (origem) e a &lt;strong&gt;master&lt;/strong&gt;. O "&lt;em&gt;merge back&lt;/em&gt;" na develop é importante, pois atualizações críticas podem ter sido adicionadas a &lt;em&gt;release branch&lt;/em&gt; e precisam estar acessíveis a novos recursos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pontos importantes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;As &lt;em&gt;branches&lt;/em&gt; master e develop são linhas contínuas, ou seja, se mantém durante todo o tempo de projeto.&lt;/li&gt;
&lt;li&gt;As &lt;em&gt;branches&lt;/em&gt; de suporte são temporárias, após concluir o propósito e as alterações retornarem para a origem, tais ramos devem ser descartados.&lt;/li&gt;
&lt;li&gt;Não há &lt;em&gt;merge&lt;/em&gt; da develop em direção a master diretamente, sempre utiliza-se as &lt;em&gt;release branches&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;As &lt;em&gt;branches&lt;/em&gt; que realizam &lt;strong&gt;&lt;em&gt;merge&lt;/em&gt; em direção a master devem gerar tags&lt;/strong&gt;, como será visto na parte prática desse artigo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Praticando
&lt;/h2&gt;

&lt;p&gt;Existem ferramentas para auxiliar no dia a dia quanto a este modelo, você não precisará se preocupar com a origem a qual a nova &lt;em&gt;branch&lt;/em&gt; será criada, para onde deve ocorrer a mesclagem quando o trabalho for concluído e se é necessário criar uma &lt;em&gt;tag&lt;/em&gt;. A ferramenta irá gerenciar isso para você. Neste artigo será apresentado uma extensão para linha de comando, como é uma extensão, tal recurso não é instalado nativamente com a instalação do Git. &lt;/p&gt;

&lt;p&gt;Considere o link abaixo e as orientações para realizar a instalação:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nvie/gitflow/wiki/Installation" rel="noopener noreferrer"&gt;https://github.com/nvie/gitflow/wiki/Installation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após a instalação:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crie um diretório em seu computador com o nome "gitflow"&lt;/li&gt;
&lt;li&gt;Acesse tal pasta utilizando o git bash&lt;/li&gt;
&lt;li&gt;Execute: &lt;code&gt;git flow init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Altere os prefixos se preferir ou pressione &lt;em&gt;enter&lt;/em&gt; para cada interação para manter o padrão.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Criando uma feature &lt;em&gt;branch&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Para iniciar o desenvolvimento de uma nova &lt;em&gt;feature&lt;/em&gt; basta executar o comando abaixo: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git flow feature start &amp;lt;NOME_FEATURE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Para esta prática, considere NOME_FEATURE igual a "cache-provider". Após executar, veja que o prefixo configurado no git flow init foi concatenado com "cache-provider". As ações internas envolveram criar uma nova &lt;em&gt;branch&lt;/em&gt; baseada na develop e um checkout em tal branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdr2brodkdaxs5xx90ip0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdr2brodkdaxs5xx90ip0.png" alt="Criando uma feature - Gitflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para demonstração do desenvolvimento da feature "cache-provider" execute os seguintes passos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;touch cache-provider.js&lt;/code&gt; (cria um arquivo em branco chamado cache-provider.js no diretório)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git add cache-provider.js&lt;/code&gt; (adiciona o arquivo na área de preparo/&lt;em&gt;staging&lt;/em&gt; para o próximo &lt;em&gt;commit&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git commit -m "adding a cache provider"&lt;/code&gt; (realiza um &lt;em&gt;commit&lt;/em&gt; que inclui o arquivo recém criado)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git flow feature finish cache-provider&lt;/code&gt; (indica que a &lt;em&gt;feature&lt;/em&gt; foi concluída e pode ser mesclada para develop)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuypcnp6re1v8cnlg0g67.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuypcnp6re1v8cnlg0g67.png" alt="Concluindo uma feature - Gitflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como visto na imagem acima, também não é necessário informar o prefixo na hora de encerrar uma &lt;em&gt;feature&lt;/em&gt;. Ao concluir uma feature as ações internas que ocorrem são: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mesclagem da &lt;em&gt;feature&lt;/em&gt; em direção a develop&lt;/li&gt;
&lt;li&gt;Remoção da &lt;em&gt;branch&lt;/em&gt; criada feature/cache-provider&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Checkout&lt;/em&gt; na branch develop &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você estiver desenvolvendo um novo recurso de forma colaborativa, seria interessante publicar a &lt;em&gt;feature&lt;/em&gt; após cada &lt;em&gt;commit&lt;/em&gt; da seguinte forma: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git flow feature publish &amp;lt;NOME_FEATURE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Criando uma hotfix &lt;em&gt;branch&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Quando um problema emergencial surge e não há a possibilidade de aguardar a próxima release pode-se utilizar hotfix. Para isso, basta executar o seguinte comando:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git flow hotfix start &amp;lt;NOME_HOTFIX&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Para esta prática, considere NOME_HOTFIX igual a "template-fix". É importante observar que este tipo de &lt;em&gt;branch&lt;/em&gt; foi criado baseado na master. Logo após a criação da &lt;em&gt;branch&lt;/em&gt; é feito um &lt;em&gt;checkout&lt;/em&gt; no ramo recém criado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j31c5vv1o6fmpnfk7ie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j31c5vv1o6fmpnfk7ie.png" alt="Criando uma hotfix - Gitflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para demonstração do desenvolvimento da hotfix execute os seguintes passos:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;touch template-fix.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add template-fix.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit -m "template bug fix"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git flow hotfix finish template-fix&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Será aberto o editor padrão para solicitar uma &lt;strong&gt;definição da tag e dos commits de merge&lt;/strong&gt; (para develop e para a master). &lt;strong&gt;Você deve informar, obrigatoriamente, ambas as descrições&lt;/strong&gt; (os merges já possuem uma descrição padrão que você pode manter, mas a tag precisa ser informada).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fninc895n4xnu39bcvnp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fninc895n4xnu39bcvnp0.png" alt="Concluindo uma hotfix - Gitflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Observe que várias ações foram promovidas: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Houve um &lt;em&gt;merge&lt;/em&gt; da &lt;em&gt;branch&lt;/em&gt; hotfix em direção a master e develop&lt;/li&gt;
&lt;li&gt;Uma tag foi criada&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;branch&lt;/em&gt; de hotfix foi deletada &lt;/li&gt;
&lt;li&gt;Houve um &lt;em&gt;checkout&lt;/em&gt; novamente para a &lt;em&gt;branch&lt;/em&gt; develop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Criando uma release branch
&lt;/h3&gt;

&lt;p&gt;A correção emergencial já consta nas duas &lt;em&gt;branches&lt;/em&gt; básicas master e develop, contudo a feature "cache-provider" ainda não está na master. &lt;strong&gt;Qualquer novo recurso ou correção não emergencial é promovido em produção através de &lt;em&gt;release branches&lt;/em&gt;&lt;/strong&gt;. Para isso execute o comando abaixo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git flow release start &amp;lt;NOME_RELEASE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26lsyrqc9ukrwoaeyxse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26lsyrqc9ukrwoaeyxse.png" alt="Criando uma release - Gitflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste momento, foi realizado &lt;em&gt;checkout&lt;/em&gt; na &lt;em&gt;branch&lt;/em&gt; do tipo release que foi criada a partir da &lt;em&gt;branch&lt;/em&gt; develop. &lt;strong&gt;Este ramo permite correções antes de ser mesclado na branch master, o que justifica um merge de volta para develop&lt;/strong&gt;. Nessa prática, não será realizado nenhum tipo de correção, por isso basta executar:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git flow release finish &amp;lt;NOME_RELEASE&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcq8wjw1p5hmsomy4ilk2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcq8wjw1p5hmsomy4ilk2.png" alt="Concluindo uma release - Gitflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Observe que várias ações foram promovidas: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Houve um &lt;em&gt;merge&lt;/em&gt; da &lt;em&gt;branch&lt;/em&gt; release em direção a master e develop&lt;/li&gt;
&lt;li&gt;Uma tag foi criada&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;branch&lt;/em&gt; de release foi deletada &lt;/li&gt;
&lt;li&gt;Houve um &lt;em&gt;checkout&lt;/em&gt; novamente para a &lt;em&gt;branch&lt;/em&gt; develop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Guia&lt;/p&gt;

&lt;p&gt;A imagem abaixo ilustra bem como você pode utilizar esta extensão para Gitflow por linha de comando.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycbcnkfdd204fkjmtqri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycbcnkfdd204fkjmtqri.png" alt="Guia Gitflow"&gt;&lt;/a&gt;&lt;br&gt;
Fonte: &lt;a href="https://danielkummer.github.io/git-flow-cheatsheet/index.pt_BR.html" rel="noopener noreferrer"&gt;https://danielkummer.github.io/git-flow-cheatsheet/index.pt_BR.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pontos de atenção
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Qualquer novo &lt;strong&gt;recurso ou bug não emergencial deve ser mesclado com a &lt;em&gt;branch&lt;/em&gt; develop somente quando este estiver confirmado na próxima release&lt;/strong&gt;. Isso porque a próxima versão que será promovida em produção é criada a partir da &lt;em&gt;branch&lt;/em&gt; develop. &lt;strong&gt;Se a cada release&lt;/strong&gt; há a necessidade de remover &lt;em&gt;commits&lt;/em&gt; pois esses foram bloqueados por algum motivo, isso certamente irá gerar um overhead muito grande para a equipe de desenvolvimento

&lt;ul&gt;
&lt;li&gt;Uma alternativa que pode minimizar esse problema é a utilização de &lt;a href="https://martinfowler.com/articles/feature-toggles.html" rel="noopener noreferrer"&gt;feature toogles&lt;/a&gt;, quando possível&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;É interessante possibilitar testes na própria ramificação de recurso ou bug não emergencial, para que qualquer erro ou um entendimento equivocado seja resolvido antes da integração com a &lt;em&gt;branch&lt;/em&gt; develop&lt;/li&gt;

&lt;li&gt;Se não há ferramentas e processos, que possibilitem os testes acima, então os testes serão realizados diretamente na branch develop. Neste caso, é muito importante que todo o time esteja comprometido em agir prontamente para qualquer erro reportado. &lt;strong&gt;Lembre, essa versão é a que será implantada em produção na próxima release&lt;/strong&gt;
&lt;/li&gt;

&lt;li&gt;Mudanças de prioridades podem ocorrer, porém se constantemente é necessário remover &lt;em&gt;commits&lt;/em&gt; da develop, talvez o Gitflow não seja o melhor fluxo de trabalho para este projeto&lt;/li&gt;

&lt;li&gt;Antes de definir o Gitflow como o modelo que será implantado, estude outros fluxos de trabalho disponíveis. &lt;strong&gt;Dependendo das necessidades você pode considerar outros mais simples&lt;/strong&gt; e que envolvam menos passos e preocupações&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Considerações finais
&lt;/h2&gt;

&lt;p&gt;Após a leitura sobre diversos artigos sobre Gitflow, um assunto que considero bastante polêmico no que tange sua utilização, o Gitflow parece funcionar bem para produtos com lançamentos feitos uma vez a cada poucas semanas, porém quando a necessidade é implantar em produção constantemente, talvez seja interessante avaliar outros fluxos de trabalho&lt;/p&gt;

&lt;p&gt;Vale destacar a própria &lt;a href="https://nvie.com/posts/a-successful-git-branching-model/" rel="noopener noreferrer"&gt;nota de reflexão&lt;/a&gt; do Vincent Driessen, criador do Gitflow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is not the class of software that I had in mind when I wrote the blog post 10 years ago. If your team is doing continuous delivery of software, I would suggest to adopt a much simpler workflow (like GitHub flow) instead of trying to shoehorn git-flow into your team.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quer aprender mais sobre Git? Aprenda no mais novo curso de &lt;a href="https://www.udemy.com/course/git-basico-ao-avancado-2021/?referralCode=D1231C6B99B30C6EDF14" rel="noopener noreferrer"&gt;Git - Básico ao avançado&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gitflow</category>
      <category>versioncontrol</category>
      <category>programming</category>
      <category>git</category>
    </item>
    <item>
      <title>Entenda as diferenças entre os tipos de merge no Git: Fast-forward X Three-way</title>
      <dc:creator>Rodrigo Santana</dc:creator>
      <pubDate>Wed, 29 Dec 2021 01:44:13 +0000</pubDate>
      <link>https://dev.to/rsantanarj/entenda-as-diferencas-entre-os-tipos-de-merge-no-git-fast-forward-x-three-way-1ghd</link>
      <guid>https://dev.to/rsantanarj/entenda-as-diferencas-entre-os-tipos-de-merge-no-git-fast-forward-x-three-way-1ghd</guid>
      <description>&lt;p&gt;Pré-requisitos&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/rsantanarj/entenda-conceitos-basicos-sobre-git-d2f"&gt;Conceitos básicos sobre Git&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como todo sistema de controle de versão (VCS) o Git dispõe de recursos de criação e união de &lt;em&gt;branches&lt;/em&gt;. Para mesclar uma &lt;em&gt;branch&lt;/em&gt; na outra, você pode considerar &lt;em&gt;merge&lt;/em&gt; ou &lt;em&gt;rebase&lt;/em&gt;. Nesse artigo será apresentado o que é um &lt;em&gt;merge&lt;/em&gt;, as estratégias envolvidas &lt;em&gt;fast-forward&lt;/em&gt; e &lt;em&gt;three-way&lt;/em&gt; e o que são conflitos e quando podem ocorrer. &lt;/p&gt;

&lt;h2&gt;
  
  
  O que é um &lt;em&gt;merge&lt;/em&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Merge&lt;/em&gt; é uma opção muito comum e útil em repositórios que possuem mais de uma &lt;em&gt;branch&lt;/em&gt; além da principal. Se é necessário fundir uma &lt;em&gt;branch&lt;/em&gt; em outra, o &lt;em&gt;merge&lt;/em&gt; pode ser uma opção.&lt;/p&gt;

&lt;p&gt;Vale lembrar que uma &lt;em&gt;branch&lt;/em&gt; no Git, é um ponteiro para um &lt;em&gt;commit&lt;/em&gt;, que será a última versão de tal ramificação. Por exemplo, considere a sequência, a qual inicialmente existe um &lt;em&gt;commit&lt;/em&gt; inicial "first commit" na &lt;em&gt;branch&lt;/em&gt; principal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U4onfXmV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdunpoxet6x77r7ap5tc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U4onfXmV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdunpoxet6x77r7ap5tc.png" alt="Merge etapa 1" width="723" height="385"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Em seguida, um novo &lt;em&gt;commit&lt;/em&gt; "setup" é realizado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--87XF__dy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3tvsogrt8uvzvmunl343.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--87XF__dy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3tvsogrt8uvzvmunl343.png" alt="Merge etapa 2" width="655" height="358"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Após isso, um contribuidor João cria uma nova &lt;em&gt;branch&lt;/em&gt; "login" a partir do &lt;em&gt;commit&lt;/em&gt; setup. Isso significa que neste momento ambas as &lt;em&gt;branches&lt;/em&gt; apontam para a mesma versão do repositório e que possuem o mesmo histórico, porém são dois ramos totalmente independentes. Qualquer nova versão em uma &lt;em&gt;branch&lt;/em&gt; não afetará a outra e vice-versa. Observe o resultado de um novo &lt;em&gt;commit&lt;/em&gt;  "creating login feature" na &lt;em&gt;branch&lt;/em&gt; "login".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y3sqDqVk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny1402kntc5gffu4vdff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y3sqDqVk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny1402kntc5gffu4vdff.png" alt="Merge etapa 3" width="777" height="470"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Note que o rótulo da &lt;em&gt;branch&lt;/em&gt; login passou a referenciar este último &lt;em&gt;commit&lt;/em&gt;, mas o rótulo da &lt;em&gt;branch&lt;/em&gt; master ainda está apontando para o &lt;em&gt;commit&lt;/em&gt; "setup". Ou seja, a &lt;em&gt;branch&lt;/em&gt; login está a um &lt;em&gt;commit&lt;/em&gt; à frente em relação a &lt;em&gt;branch&lt;/em&gt; master.&lt;/p&gt;

&lt;p&gt;E se João desejar integrar os &lt;em&gt;commits&lt;/em&gt; feitos na &lt;em&gt;branch&lt;/em&gt; login na &lt;em&gt;branch&lt;/em&gt; master, como fazer isso? Uma das opções, é através de &lt;em&gt;merge&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Merge fast-forward&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;João decide integrar a &lt;em&gt;branch&lt;/em&gt; login na &lt;em&gt;branch&lt;/em&gt; master. Para isso ele retorna para a &lt;em&gt;branch&lt;/em&gt; master com o comando abaixo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout master&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wf5Ag2pl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16cfmymsutf6o9qvtpvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wf5Ag2pl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16cfmymsutf6o9qvtpvv.png" alt="Fast-forward etapa 1" width="714" height="444"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Em seguida executa o comando:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git merge login&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6eGFw2au--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fdhnf15gh98xtboyiyl7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6eGFw2au--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fdhnf15gh98xtboyiyl7.png" alt="Fast-forward etapa 2" width="727" height="482"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Note que nessa situação, a única tarefa necessária que o Git precisou realizar foi mover o rótulo da &lt;em&gt;branch&lt;/em&gt; master para o &lt;em&gt;commit&lt;/em&gt; "creating login feature". Por isso, o nome dessa estratégia é &lt;em&gt;fast-forward&lt;/em&gt; (em português avanço rápido), pois é simplesmente uma alteração de ponteiro.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Merge three-way&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Agora considere que antes de João integrar a &lt;em&gt;branch&lt;/em&gt; login na &lt;em&gt;branch&lt;/em&gt; master, uma outra contribuidora Maria promoveu um novo &lt;em&gt;commit&lt;/em&gt; "creating user feature" na &lt;em&gt;branch&lt;/em&gt; master.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--834o-pza--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhtuz95soahpbl2g0d9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--834o-pza--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhtuz95soahpbl2g0d9p.png" alt="Three-way etapa 1" width="693" height="493"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Nesse caso, uma tentativa de &lt;em&gt;merge&lt;/em&gt; não terá o mesmo resultado do exemplo anterior. Isso porque um &lt;em&gt;commit&lt;/em&gt; foi realizado na &lt;em&gt;branch&lt;/em&gt; master após a criação da &lt;em&gt;branch&lt;/em&gt; login. Então não basta mover o ponteiro, há duas versões que precisam ser combinadas, que são o "creating user feature", &lt;em&gt;commit&lt;/em&gt; que só existe na &lt;em&gt;branch&lt;/em&gt; master e "creating login feature", &lt;em&gt;commit&lt;/em&gt; que só existe na &lt;em&gt;branch&lt;/em&gt; login. Veja a seguir o resultado de um &lt;em&gt;merge&lt;/em&gt; nessa situação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I4arfakN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhzbbjvkv7om775yzbhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I4arfakN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhzbbjvkv7om775yzbhw.png" alt="Three-way etapa 2" width="880" height="495"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Observe que foi gerado um novo &lt;em&gt;commit&lt;/em&gt; "Merge". Tal &lt;em&gt;commit&lt;/em&gt; foi gerado de forma automática pelo Git, que uniu as alterações envolvidas nos dois ramos em uma nova versão do repositório. Veja também que este novo &lt;em&gt;commit&lt;/em&gt; possui dois pais e o histórico do repositório não é mais linear. A estrutura que representa o histórico linear ou bifurcado no Git pode ser definida como DAG (&lt;em&gt;Directed Acyclic Graph&lt;/em&gt; ou Grafo Acíclico Dirigido).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conflitos
&lt;/h2&gt;

&lt;p&gt;No exemplo anterior, ao realizar um &lt;em&gt;merge&lt;/em&gt; com a estratégia &lt;em&gt;three-way&lt;/em&gt;, o Git conseguiu gerar um &lt;em&gt;commit&lt;/em&gt; de &lt;em&gt;merge&lt;/em&gt; automaticamente, pois as alterações que precisavam ser combinadas não conflitavam. Entretanto, as duas &lt;em&gt;branches&lt;/em&gt; poderiam ter alterado as mesmas linhas de um mesmo arquivo e nesse caso, o Git não pode determinar automaticamente o que está correto e é necessário decisões humanas. &lt;/p&gt;

&lt;p&gt;Os conflitos afetam apenas o contribuidor que conduz a mesclagem, o resto da equipe não tem conhecimento do conflito. O Git marcará o arquivo como conflitante e interromperá o processo de fusão. É responsabilidade desse contribuidor resolver o conflito.&lt;/p&gt;

&lt;p&gt;Por exemplo, imagine que Joao além de ter criado um novo recurso login, tenha alterado a linha 4 de um arquivo global do sistema. Maria também, além de ter criado o novo recurso de usuários, alterou a linha 4 desse mesmo arquivo. Qual alteração deve prevalecer no &lt;em&gt;commit&lt;/em&gt; de &lt;em&gt;merge&lt;/em&gt;, a alteração de Maria? Ou a alteração de João? O Git não pode determinar isso de forma automática, João que realizou a mesclagem que irá avaliar. Talvez a alteração de João seja melhor, como ele também pode considerar que a alteração de Maria faça mais sentido ou ainda, a alteração de ambos se complete.&lt;/p&gt;

&lt;p&gt;Vale destacar que conflitos só surgem em mesclagens com a estratégia &lt;em&gt;three-way&lt;/em&gt;. &lt;em&gt;Merge&lt;/em&gt; &lt;em&gt;fast-forward&lt;/em&gt; nunca irá gerar um conflito, pois não há histórico divergente a ser combinado. É somente mudança de ponteiro.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;No fast-forward&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Considere novamente a seguinte situação:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TkNyLZcG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zsbo52o6xhs3a7aibyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TkNyLZcG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0zsbo52o6xhs3a7aibyo.png" alt="No fast-forward etapa 1" width="729" height="428"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Neste caso, quando foi executado um &lt;em&gt;merge&lt;/em&gt; da &lt;em&gt;branch&lt;/em&gt; login em direção a &lt;em&gt;branch&lt;/em&gt; master, o Git assumiu a estratégia &lt;em&gt;fast-forward&lt;/em&gt; e moveu o rótulo da &lt;em&gt;branch&lt;/em&gt; master para o &lt;em&gt;commit&lt;/em&gt; "creating login feature". Porém, é possível forçar a utilização de uma estratégia &lt;em&gt;three-way&lt;/em&gt;, fazendo que o Git crie um &lt;em&gt;commit&lt;/em&gt; de &lt;em&gt;merge&lt;/em&gt;. Para isso basta incluir a opção --no-ff (no &lt;em&gt;fast-forward&lt;/em&gt;) no comando &lt;em&gt;merge&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git merge --no-ff login&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n_BIvddd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57ezibisgk81dzgbfo3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n_BIvddd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57ezibisgk81dzgbfo3r.png" alt="No fast-forward etapa 2" width="880" height="504"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Note que esta era uma situação típica de &lt;em&gt;fast-forward&lt;/em&gt;, porém com a opção --no-ff o Git foi forçado a gerar um &lt;em&gt;commit&lt;/em&gt; de &lt;em&gt;merge&lt;/em&gt;. Isso pode ser útil, ocasionalmente, caso você precise marcar pontos de mesclagem no histórico. Você só deve ter em mente que um histórico com muitos &lt;em&gt;commits&lt;/em&gt; de &lt;em&gt;merge&lt;/em&gt; pode torná-lo confuso e de difícil compreensão. Já em situações que o &lt;em&gt;merge&lt;/em&gt; seria pela estratégia &lt;em&gt;three-way&lt;/em&gt;, você não pode forçar um &lt;em&gt;fast-forward&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Merge&lt;/em&gt; sem &lt;em&gt;checkout&lt;/em&gt;, é possível?
&lt;/h2&gt;

&lt;p&gt;Nos exemplos vistos, antes de uma ação de &lt;em&gt;merge&lt;/em&gt;, foi realizado um &lt;em&gt;checkout&lt;/em&gt; na &lt;em&gt;branch&lt;/em&gt; master. Em todos os casos o objetivo era um só, incluir os &lt;em&gt;commits&lt;/em&gt; exclusivos da &lt;em&gt;branch&lt;/em&gt; login na &lt;em&gt;branch&lt;/em&gt; master, que era a &lt;em&gt;branch&lt;/em&gt; corrente com o &lt;em&gt;checkout&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Neste contexto, uma pergunta que pode surgir é sobre a possibilidade de fazer uma mesclagem entre duas &lt;em&gt;branches&lt;/em&gt;, que não são a &lt;em&gt;branch&lt;/em&gt; corrente. A resposta para esta dúvida pode ser respondida pelo texto a seguir, retirado diretamente da &lt;a href="https://stackoverflow.com/questions/3216360/merge-update-and-pull-git-branches-without-using-checkouts"&gt;fonte&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"...Você não pode mesclar uma branch B na branch A sem fazer o checkout de A primeiro, caso isso resulte em uma mesclagem sem fast-forward (three-way). Isso ocorre porque uma cópia de trabalho é necessária para resolver quaisquer conflitos em potencial. No entanto, no caso de mesclagens fast-forward, isso é possível , porque tais mesclagens nunca podem resultar em conflitos, por definição..."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Como vimos, um &lt;em&gt;merge&lt;/em&gt; pode ser executado de duas formas: por estratégia &lt;em&gt;fast-forward&lt;/em&gt; ou &lt;em&gt;three-way&lt;/em&gt;. A primeira, quando possível, será a melhor opção pois mantém um histórico linear e está livre de resolução de conflitos, pois envolve somente alteração de referência. Já a segunda, além de gerar um histórico bifurcado, com &lt;em&gt;commits&lt;/em&gt; adicionais de mesclagem, ainda está suscetível a resolução de conflitos. Esses &lt;em&gt;commits&lt;/em&gt; adicionais podem prejudicar a leitura do histórico. Ao menos que você utilize um --no-ff, o Git irá definir a estratégia de &lt;em&gt;merge&lt;/em&gt; de acordo o histórico das duas &lt;em&gt;branches&lt;/em&gt; envolvidas na mesclagem.&lt;/p&gt;

&lt;p&gt;Quer aprender mais sobre esta ferramenta essencial para desenvolvedores de software? Aprenda no mais novo curso de &lt;a href="https://www.udemy.com/course/git-basico-ao-avancado-2021/?referralCode=D1231C6B99B30C6EDF14"&gt;Git - Básico ao avançado&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>programming</category>
      <category>versioncontrol</category>
    </item>
    <item>
      <title>Entenda conceitos básicos sobre Git</title>
      <dc:creator>Rodrigo Santana</dc:creator>
      <pubDate>Tue, 07 Dec 2021 01:22:37 +0000</pubDate>
      <link>https://dev.to/rsantanarj/entenda-conceitos-basicos-sobre-git-d2f</link>
      <guid>https://dev.to/rsantanarj/entenda-conceitos-basicos-sobre-git-d2f</guid>
      <description>&lt;p&gt;Cada vez mais as empresas investem em projetos de tecnologias para facilitar negócios, automatizar tarefas, difundir informações entre vários outros propósitos. Geralmente uma das primeiras etapas de desenvolvimento de projetos é definir como você irá controlar e manter as alterações que irão ocorrer ao longo do desenvolvimento. Existem algumas ferramentas de mercado com esta finalidade.&lt;/p&gt;

&lt;p&gt;Neste artigo você irá aprender conceitos básicos sobre Git, uma ótima opção para este propósito. Entre os controles de versões disponíveis no mercado, o Git é o mais utilizado, principalmente em projetos &lt;em&gt;open source&lt;/em&gt;. Esta ferramenta armazena todas as alterações ocorridas nos arquivos do seu projeto permitindo regressões para um estado anterior. Além disso, permite que várias pessoas trabalhem simultaneamente no mesmo projeto e até nos mesmos arquivos.&lt;/p&gt;

&lt;h2&gt;
  
  
  CVCS x  DVCS
&lt;/h2&gt;

&lt;p&gt;Existem diversos sistemas de controle de versão no mercado. Há sistemas de controle de versão centralizado, o CVCS (&lt;em&gt;Centralized Version Control System&lt;/em&gt;), como Subversion (SVN), CVS e Perforce. E há sistemas de controle de versão distribuído, o DVCS (&lt;em&gt;Distributed Version Control System&lt;/em&gt;), como Git, Mercurial e Bazaar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvz23dv9rp92a7cw05vk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvz23dv9rp92a7cw05vk.png" alt="CVCSxDVCS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O CVCS possui um repositório central do projeto, geralmente localizado em um servidor, que contém todo o histórico do projeto. Qualquer membro do projeto que desejar colaborar, precisará fazer um &lt;em&gt;checkout&lt;/em&gt; de uma versão do projeto. Essa operação irá baixar uma cópia da versão selecionada para a máquina do contribuidor, porém nesta máquina não existirá o histórico do projeto. O histórico só existe no repositório central e por isso, vários comandos são executados remotamente, o que gera uma dependência de conexão à internet e explica o motivo da maioria dos comandos serem mais lentos, dado que existe o overhead da rede.&lt;/p&gt;

&lt;p&gt;O DVCS por outro lado não depende necessariamente de um repositório central. Isso porque os contribuidores podem clonar repositórios existentes ou criar seus próprios repositórios locais. Esse processo de clonagem baixa todo o conteúdo remoto e também o histórico completo do projeto. Por isso, a maioria das operações podem ocorrer localmente, sem depender de conexão com internet, o que resulta em uma velocidade maior comparado aos CVCSs. Pelo histórico estar distribuído, há uma quantidade maior de backups comparado a um CVCS, já que nesse, o histórico só existe no repositório central. Se o repositório central estiver localizado em um servidor interno vulnerável, isso poderia comprometer todo o histórico do projeto. &lt;/p&gt;

&lt;h2&gt;
  
  
  Local x remoto
&lt;/h2&gt;

&lt;p&gt;No Git é possível criar o próprio repositório através do comando &lt;code&gt;git init&lt;/code&gt;, que irá criar o diretório oculto ".git". Porém, é importante que esse repositório esteja armazenado remotamente, isso porque tal opção pode servir como backup do repositório. Para armazenamento remoto você pode considerar as plataformas de hospedagem para repositórios Git, como Bitbucket, GitLab e GitHub ou até mesmo um servidor próprio. Caso ocorra um problema irreparável em seu computador, você estará seguro pois o repositório também existe na opção que você está utilizando.&lt;/p&gt;

&lt;p&gt;Além disso, é interessante que o projeto esteja disponível remotamente para possibilitar o trabalho colaborativo. Outras pessoas podem baixar uma cópia do repositório (&lt;em&gt;clone&lt;/em&gt;), realizar modificações e enviar (&lt;em&gt;push&lt;/em&gt;) tais alterações novamente para o repositório remoto. Quando for necessário atualizar o repositório porque outro contribuidor submeteu novas versões, basta atualizar o repositório local puxando as modificações envolvidas (&lt;em&gt;pull&lt;/em&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  As três áreas
&lt;/h2&gt;

&lt;p&gt;O Git possui 3 áreas principais: a área de trabalho, a área de preparo e o repositório.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7nht8x7u0z69utwd96j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7nht8x7u0z69utwd96j.png" alt="As três áreas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A área de trabalho (&lt;em&gt;Working Directory&lt;/em&gt;) é o &lt;em&gt;checkout&lt;/em&gt; de uma versão do projeto. Corresponde aos arquivos e diretórios visíveis e alteráveis. &lt;/p&gt;

&lt;p&gt;Ao realizar qualquer alteração, seja mudança em arquivos existentes, como inclusão de novos arquivos, antes de gerar uma nova versão, você primeiramente deve adicionar tais alterações para a área de preparo (&lt;em&gt;Staging Area&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Por fim, você poderá executar um &lt;em&gt;commit&lt;/em&gt;, que irá considerar todas as alterações que estiverem na área de preparo. Isso irá produzir uma nova versão no histórico do projeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commits
&lt;/h2&gt;

&lt;p&gt;O histórico de versões no Git é formado por objetos de &lt;em&gt;commit&lt;/em&gt;. Esse histórico é baseado em uma estrutura denominada DAG (&lt;em&gt;Directed Acyclic Graph&lt;/em&gt;). Um &lt;em&gt;commit&lt;/em&gt; é uma imagem do atual estado do seu repositório. Ou seja, é uma "foto" de como está cada arquivo em um determinado momento. É possível retornar para qualquer &lt;em&gt;commit&lt;/em&gt; feito no passado.&lt;/p&gt;

&lt;p&gt;O &lt;em&gt;commit&lt;/em&gt; está associado a uma &lt;em&gt;hash&lt;/em&gt; SHA-1, tal &lt;em&gt;hash&lt;/em&gt; possui metadados como autor, data de criação, mensagem e &lt;em&gt;commit&lt;/em&gt; pai. Todos esses metadados mais o conteúdo do arquivo formam o SHA-1 do &lt;em&gt;commit&lt;/em&gt;, que é imutável. Ou seja, não pode ser alterado. Por isso, qualquer comando utilizado com o propósito de alterar algo relacionado ao commit, irá resultar em um novo SHA-1.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Branches&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Em teoria, uma &lt;em&gt;branch&lt;/em&gt; é uma ramificação de um projeto. Na prática, no Git, uma &lt;em&gt;branch&lt;/em&gt; é uma referência para um &lt;em&gt;commit&lt;/em&gt;. A &lt;em&gt;branch&lt;/em&gt; principal de um projeto chama-se “&lt;em&gt;master&lt;/em&gt;”. Porém, há iniciativas para alterar este nome a longo prazo, devido ao termo “&lt;em&gt;master&lt;/em&gt;” ser considerado racista.&lt;/p&gt;

&lt;p&gt;Há vários benefícios na utilização de &lt;em&gt;branches&lt;/em&gt; como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rápido e fácil de ser criada: 1 arquivo que contém uma referência&lt;/li&gt;
&lt;li&gt;Permitem a experimentação: Os membros da equipe podem isolar seu trabalho para que ele não afete os outros até que o trabalho esteja pronto&lt;/li&gt;
&lt;li&gt;Suporte a várias versões: As ramificações permitem suporte a várias versões do projeto simultaneamente&lt;/li&gt;
&lt;li&gt;Permitem processos de revisão de arquivo: As ramificações permitem incluir processos de revisão de arquivos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Considere a imagem abaixo como um exemplo de um repositório com mais de uma ramificação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfrzm1wavf2o8q85ibvs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfrzm1wavf2o8q85ibvs.png" alt="Repositório com mais de uma branch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na imagem acima, uma ramificação do projeto é criado a partir da versão "&lt;em&gt;first commit&lt;/em&gt;". Nesse instante, cada ramo terá seus próprios &lt;em&gt;commits&lt;/em&gt; enquanto não houver algum mecanismo de fusão entre os ramos. Os principais mecanismos de fusão são: &lt;em&gt;merge&lt;/em&gt; ou &lt;em&gt;rebase&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A referência HEAD
&lt;/h2&gt;

&lt;p&gt;A HEAD é uma referência que normalmente vai apontar para a &lt;em&gt;branch&lt;/em&gt; corrente. Já uma &lt;em&gt;branch&lt;/em&gt;, como visto anteriormente, é uma referência para um &lt;em&gt;commit&lt;/em&gt;. Este &lt;em&gt;commit&lt;/em&gt; por sua vez, será a última versão de tal ramificação. Para um melhor entendimento, considere a sequência a seguir. &lt;/p&gt;

&lt;p&gt;Inicialmente existe somente uma &lt;em&gt;branch&lt;/em&gt; chamada &lt;em&gt;master&lt;/em&gt; que aponta para o &lt;em&gt;commit&lt;/em&gt; "&lt;em&gt;first commit&lt;/em&gt;". Também existe uma referência chamada HEAD que aponta para a &lt;em&gt;branch master&lt;/em&gt;, ou seja, indiretamente aponta para o &lt;em&gt;commit "first commit"&lt;/em&gt;. Aqui existe uma referência simbólica, que ocorre quando uma referência aponta para outra referência.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa11br4oplwvpufahqqx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa11br4oplwvpufahqqx9.png" alt="Referência Head etapa 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É criado uma nova &lt;em&gt;branch&lt;/em&gt; chamada xpto a partir do &lt;em&gt;commit "first commit"&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bt823nwdcfryu903quw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5bt823nwdcfryu903quw.png" alt="Referência Head etapa 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao realizar &lt;em&gt;checkout&lt;/em&gt; na nova &lt;em&gt;branch&lt;/em&gt;, o Git altera a referência HEAD para apontar para a &lt;em&gt;branch&lt;/em&gt; xpto. Isso significa que qualquer novo &lt;em&gt;commit&lt;/em&gt; será aplicado na ponta dessa nova &lt;em&gt;branch&lt;/em&gt;. Veja o resultado de um &lt;em&gt;commit "creating service"&lt;/em&gt; na &lt;em&gt;branch&lt;/em&gt; xpto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wtyy2nc8gzhlbwgdh3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wtyy2nc8gzhlbwgdh3r.png" alt="Referência Head etapa 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Observe que se outro &lt;em&gt;commit&lt;/em&gt; for realizado, o rótulo da &lt;em&gt;branch&lt;/em&gt; xpto irá referenciar o novo &lt;em&gt;commit&lt;/em&gt;. Para a referência HEAD não há mudanças, ela permanecerá apontando para a &lt;em&gt;branch&lt;/em&gt; corrente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa25z2bje9jr4ceeun9gw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa25z2bje9jr4ceeun9gw.png" alt="Referência Head etapa 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora para gerar novos &lt;em&gt;commits&lt;/em&gt; na &lt;em&gt;branch&lt;/em&gt; principal, basta realizar primeiramente um &lt;em&gt;checkout&lt;/em&gt; na &lt;em&gt;branch&lt;/em&gt; &lt;em&gt;master&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd42z1cf3aqdq7q96n93r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd42z1cf3aqdq7q96n93r.png" alt="Referência Head etapa 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto, agora qualquer novo &lt;em&gt;commit&lt;/em&gt; será aplicado na &lt;em&gt;branch&lt;/em&gt; &lt;em&gt;master&lt;/em&gt;. Veja o resultado de um &lt;em&gt;commit "hotfix"&lt;/em&gt; nesta situação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9to2k6w280rg0ymupd1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9to2k6w280rg0ymupd1.png" alt="Referência Head etapa 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Tags&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Geralmente nos sistemas de controle de versão existe um recurso chamado &lt;em&gt;tags&lt;/em&gt; e com o Git não é uma exceção. As &lt;em&gt;tags&lt;/em&gt; são utilizadas para demarcar marcos importantes, tais marcos estão associados a um &lt;em&gt;commit&lt;/em&gt; específico. Geralmente, as pessoas utilizam esta funcionalidade para liberações de release em produção. Por exemplo, é possível marcar &lt;em&gt;commits&lt;/em&gt; com rótulos 1.0, 1.1, 1.2, 2.0 e assim por diante.&lt;/p&gt;

&lt;p&gt;Além de trazer mais organização para o histórico, as &lt;em&gt;tags&lt;/em&gt; também são referências e podem ser usadas com qualquer comando que utiliza referências como entrada. Vale destacar que diferentemente de &lt;em&gt;branches&lt;/em&gt;, que são referências mutáveis pois mudam conforme cada nova versão, as &lt;em&gt;tags&lt;/em&gt; são referências imutáveis, uma vez criadas associadas a um &lt;em&gt;commit&lt;/em&gt; elas não irão mudar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Como vimos, o Git é um sistema de controle de versão distribuído que possui diversos recursos para auxiliar na gestão de alterações. É uma ferramenta muito utilizada principalmente no contexto de software e que também permite que um grupo de pessoas possa trabalhar de forma colaborativa no mesmo projeto, editando e criando novos arquivos.&lt;/p&gt;

&lt;p&gt;Quer aprender mais sobre esta ferramenta essencial para desenvolvedores de software? Aprenda no mais novo curso de &lt;a href="https://www.udemy.com/course/git-basico-ao-avancado-2021/?referralCode=D1231C6B99B30C6EDF14" rel="noopener noreferrer"&gt;Git - Básico ao avançado&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>programming</category>
      <category>versioncontrol</category>
    </item>
  </channel>
</rss>
