Mesclar um Branch em Master no Git

Sharad Dixit 30 janeiro 2023
  1. Pré-requisitos
  2. Preparando para mesclar no Git
  3. Merge a Branch Into Master com o método merge no Git
  4. Mesclar uma ramificação no mestre com o método rebase
  5. Conclusão
Mesclar um Branch em Master no Git

Um dos recursos mais poderosos do git é a criação de ramificações e a operação de mesclagem. O Git permite que os usuários criem um novo branch e os mesclem no código de desenvolvimento. Esse recurso melhora o fluxo de trabalho do processo de desenvolvimento para vários projetos, incentivando tarefas mais específicas, menores e granulares.

Neste artigo tutorial, discutiremos diferentes abordagens para mesclar o branch do recurso git com o master.

A principal vantagem do git é seu sistema de ramificação. É nesses ramos que repousa toda a magia do GIT! O branch master carregará todas as modificações feitas. Portanto, o objetivo não é fazer as modificações diretamente neste branch, mas fazê-las em outros branches e, após vários testes, integrá-los no branch master.

Em nosso tutorial para simplificar, vamos considerar que existem dois ramos, o ramo master e o ramo de recurso conhecido como feature-1. O branch principal é o branch master que contém o código de produção, e o segundo branch é onde as modificações serão executadas ou novos recursos serão implementados. No final, se um recurso ou bug for aprovado, ele será mesclado com o master.

Initial_Repository

Vamos começar a demonstração da fusão de duas ramificações com um exemplo real. Para começar, exigimos o seguinte.

Pré-requisitos

Crie um Repositório no GitHub

Um repositório inicial pode ser criado conforme apresentado no Github

Em seguida, adicione dois arquivos no branch Master usando o botão Add file na página do repositório. Os nomes dos arquivos são os seguintes.

  • file1.txt
  • file2.txt

Neste exemplo, o conteúdo de texto a seguir é adicionado a file1.txt e file 2.txt, respectivamente.

$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file

Repositório de clones

Em seguida, clone seu repositório recém-criado do GitHub em seu sistema para criar uma cópia local do código. O URL do clone pode ser recuperado a partir do botão Código conforme abaixo.

Clone_Repository

Use o seguinte comando para clonar.

$ git clone git@github.com:project/demorepo.git

Depois de clonado com sucesso, use o seguinte comando para exibir e verificar o conteúdo dos arquivos master branch:

$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file

Criar Ramificação de Característica

$ git branch feature-1

Este comando cria um novo branch e não cria um novo commit no git.

Ramificação de recurso de checkout

Anteriormente, criamos um novo branch usando git branch feature-1. Mas, o branch ativo é o branch master. Para ativar o novo branch, use este comando no terminal:

$ git checkout feature-1
Switched to branch 'feature-1'

O comando acima mudará o branch ativo de master para feature-1. Agora, este ramo está pronto para desenvolvimento individual.

Modificar arquivos no ramo de recurso

Vamos adicionar alguns commits ou adicionar novas linhas no branch feature-1. Neste caso, file2.txt será modificado localmente e posteriormente incorporado de volta ao branch master.

Para mudanças até agora, nosso diagrama de confirmação será semelhante a abaixo. Ambos A e E representam estados de ramificação master e feature-1. Atualmente, o commit A e E são os mesmos, pois nenhum arquivo é alterado durante o checkout.

A  ← master
   \
     E  ← feature-1

Agora, file1.txt é atualizado com o novo texto. Use este comando para atualizar o conteúdo.

$ echo "file update in feature branch" > file1.txt

Agora, file2.txt tem o conteúdo abaixo.

$ cat file2.txt
This is dummy test in 2nd file

A diferença entre o conteúdo antigo e o novo em file1.txt pode ser verificada usando o comando abaixo.

$ git diff
diff --git a/file1.txt b/file1.txt
index 11d66d4..48c9378 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1,2 +1 @@
-This is dummy text line 1
-This is dummy text line 2
+file update in feature branch

Agora, prepare este arquivo e crie um commit local por meio do comando abaixo.

$ git add file1.txt
$ git commit -am "update file via feature-1"
[feature-1 22b60b8] update file via feature-1
 1 file changed, 1 insertion(+), 2 d

Um instantâneo atual da árvore de commits terá a aparência abaixo. Aqui, F é um novo commit criado na etapa anterior.

A  ← master
  \
    E --- F ← feature-1

Para demonstrar um exemplo do mundo real, o master remoto também é alterado simultaneamente por outros desenvolvedores, e essas mudanças são enviadas como commit C e commit D para master.

A --- B --- C --- D ← master
   \
      E --- F ← feature-1

Abaixo está o conteúdo atualizado de file1.txt no repositório Github no branch master. Observe que a linha 2 foi atualizada e as linhas 3 e 4 foram criadas recentemente.

File1_Content

Isso também pode ser validado localmente, visualizando seu histórico de ramificações no shell de comando em tempo real usando o comando abaixo.

$ git fetch
$ git log --all --decorate --oneline --graph

Commit_Graph

Preparando para mesclar no Git

Com o Git, temos duas possibilidades de mesclar nossas alterações de branch de recursos com o branch master remoto:

  1. O método merge
    Git merge é um comando que envia mudanças para outro branch. Ele permite aos desenvolvedores pegar suas linhas independentes de código do branch de recursos e integrá-los em um único branch no master por meio da ferramenta git merge.

  2. O método rebase
    Git rebase é outro comando usado essencialmente para o mesmo propósito, exceto que o faz de forma muito diferente.

Vamos entender as duas maneiras em detalhes:

Merge a Branch Into Master com o método merge no Git

O merge visa consolidar os branches feature e master ao commit que mantém o conteúdo de todos os branches envolvidos. O Git consegue isso, o que é conhecido como merge commit. Isso também significa que merge manipula vários ramos.

Quando os ramos divergem, ou seja, um não é ancestral do outro. O Git pode realizar a fusão fazendo um novo commit adicional que possui múltiplos pais. Na ilustração a seguir, se você tiver um commit D e um commit F em diferentes branches e misturar os branches (via git merge), o resultado é um commit G cujos pais são B e E.

A --- B --- C --- D ---	
  \				         \  
    \					  G  ← master
      E --- F --------- /	

No diagrama acima, G é um commit recém-criado e criado inteiramente pelo git. Este commit tem dois pais! e eles têm um pedido:

  • O primeiro pai é D, que era master anteriormente.
  • O segundo pai é F, que era feature-1 anteriormente.

Esse tipo de confirmação é chamado de confirmação de mesclagem.

Agora volte para o nosso exemplo de repositório e mescle o branch feature-1 recém-criado para master

Primeiro, verifique o branch master.

$ git checkout master

Agora, puxe as alterações do mestre remoto para o master local.

$ git pull origin master

From github.com:repo/demorepo

 * branch            master     -> FETCH_HEAD
   Updating 17cc6b4..a802b6b
   Fast-forward
    file1.txt | 5 ++++-
    1 file changed, 4 insertions(+), 1 deletion(-)

Depois, use o comando abaixo para mesclar a ramificação do recurso, ou seja, feature-1, para a ramificação atualmente ativa.

$ git merge feature-1

O branch feature-1 será totalmente mesclado com o branch master se esta etapa for concluída com sucesso. No entanto, se o git não puder resolver esses conflitos de mesclagem automaticamente, ele falhará com um erro de conflitos de mesclagem.

Este é um cenário muito típico; isso pode acontecer quando duas ramificações modificam a mesma parte do arquivo e o git não consegue resolver qual parte usar. É exatamente o que acontece com nosso exemplo. Este caso é mostrado abaixo via git.

Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.

Sempre que o git encontra um conflito, ele adiciona <<<<<<< & ======= para destacar a seção que causou o conflito e que precisa ser resolvido manualmente.

File1_MergeConflict

Uma vez decidido qual parte manter na versão master final do arquivo, um indivíduo deve remover o código irrelevante (incluindo indicadores de conflito). Eventualmente, envie as alterações para o branch remoto conforme abaixo.

$ git add .
$ git commit -am "resolving the mergeconflict"
[master 1acce69] resolving the mergeconflict
$ git push

Desta forma, o branch feature-1 é mesclado com sucesso ao master remoto.

A seguir, verificaremos o histórico de ramificações novamente com o comando abaixo.

git log --all --decorate --oneline --graph

Merge_Graph

Podemos verificar se git merge criou um Merge Commit com commit-id como 1acce69 para fundir o branch feature-1 com origin/master.

Mesclar uma ramificação no mestre com o método rebase

Mais uma vez, considere a situação em que nossas ramificações de recurso e mestre estão fora de sincronia e precisam ser mescladas. Vamos também relembrar a ilustração que mostra essa situação anteriormente.

A --- B --- C --- D ← master
   \
      E --- F ← feature-1

Como uma forma alternativa de mesclar, você pode mesclar o branch feature-1 no branch master com a opção de rebase. O rebase unifica os branches envolvidos simplesmente colocando os commits do branch feature na frente do branch master.

Isso será feito por meio dos comandos abaixo,

git checkout master
git pull
git checkout feature-1
git rebase master

Podemos ter a ilustração abaixo após executar o rebase.

A --- B --- C --- D----(operation rebase)----- E--------F   ← master

Pela ilustração acima, é visível que algo bom que o rebase faz é produzir um histórico de commits linear, mais limpo e mais fácil de ler. Ao mesclar, ele também não gera aquele estranho merge commit adicional.

A desvantagem dessa abordagem é que o rebase altera toda a estrutura dos branches envolvidos, incluindo a reescrita do histórico de commit desses branches. Como rebase não cria um merge commit, você não obtém a rastreabilidade de quando dois ramos se fundiram, pois o rebase gera um ramo linear no final do processo.

Conclusão

Ambos os comandos são muito úteis; no entanto, em diferentes situações, cada lado tem vantagens conforme abaixo.

Git rebase

  • Simplifique uma história complexa.
  • Evite mesclar ruído de commit em repositórios com ramos ocupados.
  • Arriscado se não for usado corretamente, pois não preserva a história.

Git merge

  • Simples de usar.
  • Como um commit extra de mesclagem é criado toda vez, faz com que o histórico de commits pareça confuso e sujo.
  • Preserva a história completa e a ordem cronológica.

Artigo relacionado - Git Merge