W3docs

git merge

Saiba como funciona o comando git merge, a diferença entre mesclagem fast-forward e mesclagem de 3 vias, e como resolver conflitos.

O comando git merge une duas ou mais linhas de desenvolvimento. Quando você termina um recurso em seu próprio branch, o git merge pega o trabalho daquele branch e o incorpora ao branch em que você está atualmente, produzindo um histórico combinado único.

Esta página aborda o que acontece durante uma mesclagem, a diferença entre uma mesclagem fast-forward e uma mesclagem de 3 vias, como forçar um commit de mesclagem e como reconhecer e resolver um conflito de mesclagem.

Ele funciona em conjunto com git branch (para criar e excluir branches), git checkout (para mudar para o branch receptor) e git pull (para atualizar antes de mesclar). Se você preferir um histórico linear sem commits de mesclagem, veja git rebase como alternativa.

Como funciona

O uso principal do git merge é combinar dois branches. Ele também é usado para integrar múltiplos commits de um branch em outro. Na ilustração a seguir, o git merge pega dois pontos de branch e encontra um commit ancestral comum entre eles. O commit base comum é usado para criar um novo commit de mesclagem que combina as alterações de ambos os branches. Aqui temos dois branches: master e stage. Devemos mesclar o branch stage no branch master.

gitmerge

Os commits de mesclagem são únicos porque têm dois commits pai. O Git combina automaticamente histórias separadas ao criar um novo commit de mesclagem. No entanto, se ambos os branches modificarem as mesmas linhas, o Git não pode combiná-los automaticamente, resultando em um conflito de mesclagem.

gitmerge1

Processo de mesclagem

Antes de iniciar o processo de mesclagem, siga estas etapas:

  • Certifique-se de estar no branch receptor correto. Execute git checkout <branch receptor> para mudar para ele.
  • Atualize o branch de destino com as últimas alterações remotas. Execute git pull para buscar e integrar os commits remotos mais recentes.
  • A etapa final é executar git merge <nome do branch>, que especifica o branch a ser mesclado no branch receptor.

Mesclagem fast-forward

Uma mesclagem fast-forward ocorre quando o caminho do branch atual para o branch de destino é linear. A mesclagem fast-forward combina os históricos, pois todos os commits acessíveis a partir do branch de destino estão disponíveis por meio do branch atual. Veja um exemplo de mesclagem fast-forward:

gitmerge2

Quando os dois históricos divergem, o Git usa a mesclagem de 3 vias como alternativa. A mesclagem de 3 vias usa um commit dedicado para combinar dois históricos.

gitmerge3

As mesclagens fast-forward são normalmente usadas para pequenos recursos ou correções de bugs, enquanto as mesclagens de 3 vias são usadas para integrar recursos de longa duração. Os exemplos a seguir usam uma mesclagem fast-forward:

git merge

# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Merge in the stage branch
git checkout master
git merge stage
git branch -d stage

Executamos git branch -d para excluir o branch stage, pois ele agora está acessível a partir do branch master.

O comando git merge com a opção --no-ff é executado caso você precise de um commit de mesclagem durante uma mesclagem fast-forward para mesclar o branch especificado no branch atual, sempre gerando um commit de mesclagem (mesmo no caso de uma mesclagem fast-forward):

git merge --no-ff

git merge --no-ff <branch>

Mesclagem de 3 vias

Este cenário requer uma mesclagem de 3 vias quando o branch master avança enquanto o branch stage ainda está em desenvolvimento. Isso é usado quando membros da equipe trabalham simultaneamente em um recurso grande:

o comando git merge

# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Develop the master branch
git checkout master
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to master"
# Merge in the stage branch
git merge stage
git branch -d stage

No exemplo acima, stage seria um recurso maior que leva muito tempo para ser desenvolvido, razão pela qual usamos uma mesclagem de 3 vias. Se o seu recurso for pequeno, é melhor usar uma mesclagem fast-forward para evitar commits desnecessários que poluam o histórico do projeto.

Opções úteis de mesclagem

Essas flags alteram o comportamento do git merge:

OpçãoO que faz
--no-ffSempre cria um commit de mesclagem, mesmo quando um fast-forward é possível. Mantém o branch de recurso visível no histórico.
--ff-onlyMescla apenas se um fast-forward for possível; caso contrário, aborta. Útil em scripts para recusar um commit de mesclagem.
--squashCombina todos os commits do branch em um único conjunto de alterações preparadas (você então faz o commit manualmente). Sem commit de mesclagem e sem segundo pai.
--abortPara uma mesclagem com conflito e restaura o branch ao estado anterior à mesclagem.
-m "<msg>"Define a mensagem do commit de mesclagem diretamente em vez de abrir um editor.

Uma mesclagem squash é útil quando um branch de recurso tem muitos commits pequenos de "trabalho em andamento" que você não quer no histórico principal:

git merge --squash

git checkout master
git merge --squash stage
git commit -m "Add stage feature"

Resolvendo conflitos

Ao mesclar dois branches, se a mesma parte do mesmo arquivo for alterada, ocorrem conflitos de mesclagem porque o Git não consegue determinar qual versão usar. Quando isso acontece, o Git para antes de criar o commit de mesclagem para permitir que você resolva o conflito. O processo de mesclagem do Git usa um fluxo de trabalho de editar/preparar/commit para resolver conflitos de mesclagem. Quando um conflito ocorre, executar git status exibirá os arquivos que precisam ser resolvidos. A imagem a seguir aparecerá quando as mesmas partes do arquivo example.txt tiverem sido alteradas:

git status

On branch master
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: example.txt

Se você decidir não prosseguir com a mesclagem, poderá cancelá-la a qualquer momento executando git merge --abort.

Como os conflitos são apresentados

No caso de conflitos, o Git edita o conteúdo dos arquivos afetados com marcas visuais em ambos os lados do conteúdo conflitante. Conflitos só podem ocorrer durante uma mesclagem de 3 vias — uma mesclagem fast-forward nunca conflita, porque o branch receptor não tinha novos commits próprios para colidir.

Os marcadores principais são <<<<<<<, ======= e >>>>>>>. Eles ajudam a localizar as seções conflitantes nos seus arquivos.

git conflicts

here is some content not affected by the conflict
<<<<<<< master
this is conflicted text from master
=======
this is conflicted text from stage branch
>>>>>>> stage

Para resolver o conflito, abra o arquivo, exclua as três linhas de marcadores (<<<<<<<, =======, >>>>>>>), e edite o texto restante para a versão que deseja manter. Em seguida, execute git add <file> no arquivo conflitante para marcá-lo como resolvido, e execute git commit para criar o commit de mesclagem.

Um exemplo completo

A sessão abaixo cria dois branches que editam a mesma linha, mescla-os, encontra um conflito, resolve-o e conclui a mesclagem. Você pode colar esses comandos em qualquer diretório vazio para reproduzi-lo exatamente.

reproduzir um conflito e resolvê-lo

git init demo && cd demo
echo "line one" > file.txt
git add file.txt
git commit -m "Initial commit"

# Create a branch and change the line there
git checkout -b stage
echo "change from stage" > file.txt
git commit -am "Edit on stage"

# Change the same line on master
git checkout master
echo "change from master" > file.txt
git commit -am "Edit on master"

# Merge stage into master -> conflict
git merge stage
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
# Automatic merge failed; fix conflicts and then commit the result.

Após editar file.txt para manter a versão desejada, conclua a mesclagem:

git add file.txt
git commit -m "Merge stage, keep resolved line"
git branch -d stage

Verificando uma mesclagem

Após mesclar, confirme o resultado com git log. As flags --graph e --oneline desenham a topologia do branch para que um commit de mesclagem (com dois pais) seja fácil de identificar:

git log --oneline --graph

Se você decidir que uma mesclagem concluída foi um erro, git reset pode mover o branch de volta ao commit anterior à mesclagem.

Prática

Prática
Quais são os principais recursos e processos envolvidos no comando 'git merge'?
Quais são os principais recursos e processos envolvidos no comando 'git merge'?
Was this page helpful?