Como dar merge em branches usando GIT?

Um passo a passo detalhado de como mergear com cautela usando GitHub e Visual Studio Code.

Lorena Vilaça
Apple Developer Academy | UFPE
9 min readMay 20, 2023

--

Árvore de commits com um merge

Uma das coisas que tive bastante dificuldade quando iniciei minha jornada como programadora foi entender como funcionava o GIT. Eram muitos comandos e um funcionamento que parecia simples, mas não fazia sentido na minha cabeça. Porém, quando se trabalha em equipe, GIT se torna uma ferramenta essencial.

Usar GIT é uma forma muito mais segura de desenvolver projetos em grupo, já que ele é um sistema de controle de versão distribuído, o que permite o registro de alterações feitas em um código e que a equipe regrida a versões anteriores de uma aplicação de modo simples e rápido.

A funcionalidade que mais demorei a aprender foi o merge entre branches, ou seja, a junção de duas branches em uma só. Eu não sabia qual era a sequência de comandos, como resolver conflitos e tinha medo de mergear de forma errada e perder partes importantes do projeto. Por isso, decidi fazer um passo a passo direto de como mergear e resolver conflitos de forma cuidadosa.

É importante ressaltar que esse tutorial será feito em um Mac, então a parte visual de um terminal pode ser diferente do seu, mas os comandos são os mesmos.

Passo a passo

Passo 1: Adicionar alterações ao repositório remoto

Antes de qualquer ação é importante checar em qual branch estamos trabalhando, isso pode ser checado facilmente com o comando git branch no terminal.

Terminal com uma lista de branches

No caso acima, pode-se perceber que estamos na branch feature/homescreen, que está em verde e com um asterisco, onde as alterações estão sendo feitas.

Agora devemos adicionar os arquivos alterados. Para saber quais foram as alterações podemos usar o comando git status, que fornece uma lista com várias informações importantes, inclusive os arquivos que sofreram alterações locais.

Com o comando git add . adicionamos todos esse arquivos a um estado de "preparação" para serem enviados ao servidor remoto. Caso queira adicionar apenas arquivos específicos, o ponto do final do comando pode ser trocado pelo caminho do arquivo selecionado.

Terminal com arquivos sendo adicionados ao git

Observe que os arquivos ficam na cor verde quando estão adicionados. Caso queira remover algum arquivo desse status, o comando git restore --staged <SubstituaPeloNomeDoArquivo> retira ele dos adicionados.

Em seguida, vamos criar um commit dessas alterações com o comando git commit -m "SuaMensagemDoCommit". Commits servem para salvar o estado atual do seu projeto e permitem que você volte para estados antigos.

É interessante que exista um fluxo padrão no uso do GIT, que definirá tanto a nomeação e criação das branches quanto dos commits, o que chamamos de git flow. Entender esse fluxo te ajudará a aprender como empresas e equipes trabalham com o GIT. Você pode ler um pouco sobre git flow neste artigo.

Para finalizar esse passo, precisamos enviar esse commit criado para o servidor remoto. Caso seja a primeira vez que você envia alterações para essa branch, é necessário fazer uma configuração de para onde elas serão enviadas remotamente com o comando git push --set-upstream origin <NomeDaSuaBranch>. Se não for a primeira vez, apenas o comando git push servirá para enviar os arquivos.

Terminal com um commit e um push sendo feitos

Agora as alterações feitas localmente encontram-se remotamente na branch na qual estamos trabalhando.

Passo 2: Pull request para outra branch

O próximo passo é abrir uma solicitação nesse repositório, que vai informar aos outros desenvolvedores colaboradores que foram feitas alterações em uma branch e que elas estão tentando ser enviadas a outra branch. Chamamos essa solicitação de Pull request. Com essa notificação criada pelo pull request você ainda permite que seu time revise suas alterações antes de aceitá-las na branch que você pediu.

Para criar nosso Pull request, vamos abrir a página do repositório no GitHub. Observe que o site reconhece que tiveram mudanças recentes em uma branch e já adiciona na página inicial um botão de Compare & pull request.

Página inicial de um repositório no GitHub

Clicando no botão somos redirecionados para uma página onde podemos configurar nosso pull request.

Nessa etapa é muito importante checar para qual branch estamos tentando enviar as alterações. Isso pode ser facilmente observado nos campos base e compare, o primeiro corresponde à branch onde as alterações serão recebidas e o segundo onde elas foram feitas. Na imagem abaixo veja que a solicitação é de enviar o que está na branch feature/homescreen para a main.

Página de abrir um pull request no GitHub

Um problema que pode surgir durante o processo de merge é o conflito entre branches. Conflitos aparecem quando duas ramificações diferentes editam a mesma linha ou linhas consecutivas do mesmo arquivo, ou quando arquivos são excluídos na ramificação, mas editados em outra. Nessas situações o GIT não sabe qual edição deve permanecer no projeto, então é necessário fazer esse conserto manualmente.

Observe que, na imagem acima, uma mensagem em vermelho de "Can't automatically merge" indica que há conflitos a serem resolvidos. Por isso, precisamos descobrir em que arquivos estão esses conflitos e indicar qual das duas versões das ramificações deve permanecer. Caso apareça uma mensagem em verde de "Able to merge" não há nenhum conflito a ser resolvido e você conseguirá finalizar o processo do pull request com mais facilidade.

Independente de ter dado ou não algum conflito, vamos seguir com o processo de abrir a solicitação clicando no botão Create pull request.

Página de um pull request com conflitos no GitHub

A tela seguinte vai mostrar uma lista com todos os arquivos onde existem conflitos e o GitHub te dá a possibilidade de resolver esses conflitos pelo próprio site. É mais recomendado que você utilize alguma IDE para isso. Uma IDE, isto é, um ambiente de desenvolvimento integrado, nada mais é que uma ferramenta de desenvolvimento que reúne ferramentas de apoio ao desenvolvimento de software, inclusive algumas te ajudam a analisar as diferenças nas linhas de código e indicam exatamente onde os conflitos estão presentes.

Passo 3: Resolver conflitos gerados

Como o GitHub já nos disse que existem arquivos conflitando, vamos dar merge nessas duas ramificações para resolver esses conflitos. Git merge é o comando que une históricos bifurcados, ou seja, ele pega duas ramificações criadas a partir das branches e integram elas em uma ramificação só.

Por medida de segurança, é ideal que essa junção seja feita na branch que estamos trabalhando, dessa forma o que já existe na branch principal não é alterado até se ter mais segurança de que está tudo funcionando corretamente.

Como vamos fazer esse merge localmente, a primeira etapa é dar um pull de tudo que está na branch principal para a nossa máquina, assim não sobrescrevemos nenhuma alteração feita anteriormente. Essa branch principal é a mesma que colocamos como base no Passo 2.

No terminal, vamos trocar para essa ramificação com o comando git checkout <NomeDaBranchPrincipal> e em seguida dar um git pull para termos a certeza que estamos com a versão mais recente dos arquivos principais. Depois disso, vamos voltar para a branch que estávamos trabalhando com um git checkout <NomeDaBranchQueTrabalhamos>.

Terminal com mudanças entre branches e um pull em uma delas

Com todas as versões atualizadas, podemos seguir com o merge usando o comando git merge <NomeDaBranchPrincipal>. O terminal nos dará uma mensagem de erro que, assim como o GitHub, vai indicar os arquivos que possuem os conflitos que precisamos resolver.

Terminal com um merge entre branches que gerou um conflito

Para resolver esses conflitos, utilizaremos como IDE o Visual Studio Code.

Quando você abrir o Visual Studio Code, ou VS Code, a tela inicial já nos dá a opção de abrir uma pasta. Abra a pasta do repositório e assim vamos ter acesso a todos os arquivos do projeto dentro do VS Code.

Tela inicial do Visual Studio Code com retângulo vermelho na opção de abrir uma pasta

Do lado esquerdo da IDE você verá uma lista com todos os arquivos daquele projeto. Os arquivos com o nome em vermelho são os que possuem conflitos a serem resolvidos.

O passo agora é indicar qual versão do arquivo deve permanecer. É necessário ter muito cuidado e atenção nessa parte, mas não pense que é um bicho de 7 cabeças, é mais fácil que parece.

Observe abaixo que existem dois blocos de texto, um numa cor esverdeada indicado com um HEAD (Current Change) e outro num tom de azul indicado por <NomeDaSuaBranchPrincipal> (Incoming Change). Esses blocos de texto são exatamente onde o GIT encontrou um conflito que não soube resolver.

Arquivo no Visual Studio Code com um conflito

O bloco esverdeado são as alterações da branch em que você está, por isso são indicadas por Current Change. Essas mudanças são as linhas que você adicionou ou editou, que nesse exemplo são as alterações que fizemos na branch feature/homescreen e que queremos que estejam na branch principal.

Já o bloco em azul, indicado por Incoming Change, são as mudanças da ramificação que tentamos dar o merge, que nesse exemplo é a main.

O VS Code dá 4 possibilidades rápidas de resolução de conflitos nos botões logo acima do bloco verde:

  • Accept Current Change: deixar no arquivo apenas as alterações do bloco de texto esverdeado.
  • Accept Incoming Change: deixar no arquivo apenas as alterações do bloco de texto azul.
  • Accept Both Changes: deixar no arquivo ambas as alterações dos blocos de textos.
  • Compare Changes: possibilita que você veja lado a lado como cada um dos arquivos estão, assim fica mais fácil analisar as diferenças entre eles.

Essa parte é muito relativa ao que você precisa para que o projeto funcione normalmente. No exemplo, queremos que as duas alterações continuem presentes, então vamos escolher a terceira opção. E pronto, esse conflito está resolvido!

Repita o processo para os outros conflitos existentes até todos estarem resolvidos e não podemos esquecer de salvar todos os arquivos após as resoluções, caso contrário o GIT não vai reconhecer que as alterações foram feitas.

É assim que o exemplo ficou após salvar:

Arquivo no Visual Studio Code após resolução de conflitos

É de extrema importância que, antes de adicionarmos esse novo arquivo ao repositório remoto, rodemos o projeto para confirmar que tudo está funcionando como o esperado. Isso dificulta que algum erro nas resoluções dos conflitos deixe nosso projeto com um mal funcionamento.

Voltando para o terminal, repetiremos o processo do primeiro passo de enviar para o repositório remoto com o comando git add . e em seguida o git commit -m "SuaMensagemDoCommit". Por último, usamos o git push e enviamos os novos arquivos sem conflitos para o GitHub.

Terminal enviando alterações locais para repositório remoto

Passo 4: Finalizar o pull request

Agora, com todos os conflitos resolvidos, podemos voltar para a página de pull requests do GitHub.

Ao invés da mensagem dos conflitos, um botão de Merge pull request aparecerá no lugar. Clicando nele e em seguida no botão Confirm merge o processo de junção das branches será finalizado.

Página de um pull request sem conflitos no GitHub
Pedaço de uma página de confirmação de merge no GitHub

É assim que a página ficará depois do merge:

Página de um pull request mergeado no GitHub

Apesar de ser um processo aparentemente longo e trabalhoso, fica mais fácil à medida que exercitamos. E, se você chegou até aqui, espero que esse tutorial tenha te ajudado a entender o processo!

--

--