Conceito de Merge — Git e Github
Tags: git, github, programming, braziliandevs
Published: 2022-01-13 14:41:43

Após conhecermos a tão famosa **Branch** que tem como propósito *dividir* a linha original do desenvolvimento do projeto, precisamos *"trazer"* de volta para a branch main/master, dei uma breve explicação de como fazer isso em *[Conceito de branch](https://dev.to/eduardoopv/conceito-de-branch-git-e-github-2bfe)*, porém chegou a hora de se aprofundar no **merge** e resolver os possíveis conflitos que irão aparecer(uma hora ou outra).

---

## Merge 

O [merge](https://git-scm.com/book/pt-br/v2/Branches-no-Git-O-b%C3%A1sico-de-Ramifica%C3%A7%C3%A3o-Branch-e-Mesclagem-Merge)(mesclagem) é o jeito do Git de pegar duas branchs e unificar em apenas um histórico. O comando `git merge` permite que você pegue as linhas de desenvolvimento independentes criadas pelo `git branch` e junta elas em apenas uma ramificação.

É de extrema importância ter algo bem claro na hora de realizar um merge, sempre a branch que você está **(HEAD)** vai ser a que vai "receber" a branch, sendo atualizado para refletir a mesclagem, a branch alvo não sofre nenhum tipo de alteração.

`git merge` é usado sempre depois do `git checkout` para selecionar o branch atual que irá receber e com o `git branch -d` para excluir o branch alvo obsoleto.


![Ilustração de varias ramificações](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d0tg9kcg9dlp2vuy5hbd.jpg)

---

## Merge na prática

Vamos utilizar um exemplo prático, digamos que você desenvolveu um *Header* bem básico representado pela branch *feat/header (Nomenclatura tirada do [Git Flow](https://www.atlassian.com/br/git/tutorials/comparing-workflows/gitflow-workflow), explicarei futuramente)*.

![Branch criada com o header](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cxymop9un20l1zge3mrt.png)
 
 
Depois de ter criado uma branch com `git checkcout -b feat/header` *(Lembrando que a flag -b do checkout cria uma branch e já move para ela)*, realizamos as criações necessárias e commitamos o arquivo `index.html` com `git commit -am "feat: header"`*(Lembrando que a flag -am adiciona os arquivos e já realiza o commit)*. 

Agora o que precisamos fazer para juntar essa nova feature na branch principal, precisamos ir para a branch receptora, sempre atento para onde o HEAD está apontado, e realizamos o merge. Uma vez que a branch ficou obsoleta podemos excluir ela.

![Output após o comando merge](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xv50fa19tamwks65obow.png)
 
---

## Resolvendo Conflitos

Durante o processo de criação e branchs e a junção com o merge, é possível que mais de um desenvolvedor edite a mesma linha de código, com isso o Git gera um conflito, por ter dois commits o Git não sabe qual utilizar, e não consegue resolver esse problema sozinho, é necessário que o usuário decida qual é o correto.

Digamos que você ficou responsável por editar um link do header e um colega recebeu uma task para alterar a logo do footer, porém acabou adicionando alguns caracteres sem querer no link que você está alterando.

Primeiro você cria uma nova branch de correção e realiza a alteração, cria um commit e mescla com a branch master, durante esse processo um colega adicionou o caractere acidental e realizou um commit na master.
 
Nossa alteração:
![Alterações no Index.html](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tf9bhrnpy7kpsx4fjah.png)
 
Acidente: 
![Index.html com as alterações acidentais](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ys7bgr54ci700kzdsh18.png)

Você finalizou todas as alterações e da um `git checkout master` que será a branch receptora, e realiza o `git merge fix/header`, e acaba vendo um output no terminal *CONFLICT*, e repara que algo mudou no editor de texto ([Visual Studio Code](https://code.visualstudio.com/)).

Terminal: 
![Output terminal conflict](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ipvy4mcdaf78ezogm36m.png)

Visual Studio Code:
![Vistual Studio Code resolvendo conflito](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ygsgjuxkkrgzwzu63p7s.png)
 
Reparamos que ele adicionou alguns caracteres:
`<<<<<<<` Branch receptora (HEAD)
`>>>>>>>` Branch de mesclagem (fix/header)
`=======` Separa as branchs, o de cima represente a branch recepctora e de baixo a de mesclagem.

E podemos ver que existe um menu (clicavel) acima do conflito, nele existe algumas opções rápidas que podemos realizar, as mais importantes são:

`Accept Current Change`: Irá aceitar a branch receptora, nesse caso ele iria manter os caracteres acidentais.
`Accept Incoming Change`: Irá aceitar a alteração realizada no header, nesse caso seria "Conheça nossa empresa"
`Accpet Both Changes`: Ele aceita as duas modificações, criando então duas linhas, uma com os caracteres e outra com as alterações.

No nosso caso queremos aceitar apenas o `Accept Incoming Change` para manter as alterações que realizamos na branch `fix/header`, podemos ver que nada muda, por que os arquivos conflitantes agora estão como *"[Unmerged](https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging) patch"*, precisamos adicionar ele no próximo commit `git add .` e criar um commit de resolução `git commit -m "resolve conflitos no header"`. 

![Terminal de commit do conflito](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/klwqxajl58krft2qmb0m.png)
 
---

E pronto temos o nosso conflito mais comum de acontecer resolvido e já podemos excluir a branch obsoleta das modificações.