Git merge
Mesclagem é o jeito do Git de unificar um histórico bifurcado. O comando git merge
permite que você pegue as linhas de desenvolvimento independentes criadas pelo git branch
e as integre em uma ramificação única.
Observe que todos os comandos apresentados abaixo fazem o merge para o branch atual. O branch atual vai ser atualizado para refletir a mesclagem, mas o branch alvo não vai sofrer alterações. Então é importante ressaltar: o git merge
é usado com frequência em conjunto com o git checkout
para selecionar o branch atual e com o git branch -d
para excluir o branch alvo obsoleto.
Como funciona
O Git merge
vai combinar várias sequências de commits em um histórico unificado. Nos casos de uso mais frequentes, o git merge
é utilizado para combinar dois branches. Os exemplos a seguir neste documento vão focar neste padrão de mesclagem de branch. Nestes cenários, o git merge
pega dois indicadores de commit, em geral, as pontas do branch e encontra um commit base em comum entre eles. Assim que o Git encontra um commit base em comum, ele cria uma nova "confirmação de mesclagem" combinando as alterações de cada sequência de merge commit enfileirada.
Imagine que você tem uma nova função de ramificação baseada na ramificação main
. Agora, você quer fazer merge dessa função de ramificação com a main
.
Material relacionado
Log avançado do Git
VER SOLUÇÃO
Aprenda a usar o Git com o Bitbucket Cloud
Executar este comando faz merge da função especificada na ramificação atual, por exemplo, a main
. O Git define o algoritmo de merge com automação (discutido abaixo).
Os commits de mesclagem são únicos em relação a outros commits, devido ao fato de que terem dois commits pai. Ao criar um commit de mesclagem, o Git vai tentar mesclar automaticamente os históricos separados para você. Caso o Git encontre um pedaço de dados que está alterado em ambos os históricos, ele não vai ser capaz de fazer essa combinação. Este cenário é um conflito de controle de versão, e o Git vai precisar da intervenção do usuário para continuar.
Preparação para a mesclagem
Antes de realizar uma mesclagem, existem algumas etapas de preparação para garantir que a mesclagem dê certo.
Confirmar o branch receptor
Execute o git status
para ter certeza de que HEAD
está apontando para a ramificação receptora do merge correta. Se necessário, execute git checkout
para alterar para a ramificação receptora. Nesse caso, vamos executar git checkout main
.
Buscar os commits remotos mais recentes
Verifique se a ramificação receptora e a ramificação que vai ser mesclada estão atualizadas com as alterações remotas mais recentes. Execute o comando git fetch
para enviar o pull dos commits remotos mais recentes. Assim que a busca for concluída, veja se a ramificação main
tem as atualizações mais recentes executando o comando git pull
.
Mesclagem
Após a conclusão das etapas de "preparação para mesclagem" discutidas antes, a mesclagem pode ser iniciada executando git merge
em que
é o nome do branch que vai ser mesclado no branch receptor.
Mesclagem de avanço rápido
Um merge de avanço rápido pode ocorrer quando existe um caminho linear da ponta da ramificação atual até a ramificação alvo. Em vez de fazer merge de fato das ramificações, tudo o que o Git precisa fazer para integrar os históricos é mover (ou seja, fazer o "avanço rápido") a ponta da ramificação atual até a ponta da ramificação alvo. Assim, os históricos são combinados com eficiência, uma vez que todos os commits acessíveis na ramificação alvo agora estão disponíveis na atual. Por exemplo, o merge de avanço rápido de alguma função para a ramificação main
seria parecido como o seguinte:
No entanto, uma mesclagem de avanço rápido não é possível se os branches tiverem divergido. Quando não há um caminho linear para o branch alvo, o Git não tem escolha a não ser fazer a combinação por meio da mesclagem de três vias. As mesclagens de três vias usam um commit dedicado para juntar os dois históricos. A nomenclatura vem do fato de que o Git usa três commits para gerar o commit de mesclagem: as duas pontas do branch e seu ancestral em comum.
Embora você possa usar qualquer uma destas estratégias de mesclagem, muitos desenvolvedores gostam de usar mesclagens de avanço rápido (facilitadas por meio do rebase) para fazer pequenas correções de funções ou bugs, reservando as mesclagens de três vias para a integração de recursos de maior execução. No último caso, o commit de mesclagem resultante serve como uma união simbólica dos dois branches.
O primeiro exemplo demonstra uma mesclagem de avanço rápido. O código abaixo cria um branch, adiciona dois commits a ele e, então, a integra à linha principal com uma mesclagem de avanço rápido.
# Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Merge in the new-feature branch
git checkout main
git merge new-feature
git branch -d new-feature
Este é um fluxo de trabalho comum para ramificações atuais com pouco tempo de vida que são mais usadas como um desenvolvimento isolado do que uma ferramenta organizacional para funções de maior execução.
Observe também que o Git não deve reclamar sobre o git branch -d
, uma vez que a nova função está agora acessível na ramificação principal.
Caso você precise do commit de mesclagem durante uma mesclagem de avanço rápido para fins de manter registros, você pode executar o git merge
com a opção --no-ff
.
git merge --no-ff <branch>
Este comando vai mesclar o branch especificado com o branch atual, mas sempre gerando um commit de mesclagem (mesmo no caso da mesclagem de avanço rápido). Isto é útil para documentar todas as mesclagens que ocorrem no repositório.
Mesclagem de 3 vias
O próximo exemplo é bem parecido, mas requer um merge de três vias, pois a ramificação main
progride enquanto a função está em progresso. Este é um cenário comum para funções grandes ou quando muitos desenvolvedores estão trabalhando no projeto ao mesmo tempo.
Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Develop the main branch
git checkout main
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to main"
# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature
Observe que é impossível para o Git realizar um merge de avanço rápido, pois não há como mover a ramificação main
até o new-feature
sem retroceder.
Para a maioria dos fluxos de trabalho, a new-feature
seria uma função muito maior, que levou muito tempo para ser desenvolvida, o que explicaria os novos commits aparecendo na ramificação main
nesse meio tempo. Caso a ramificação de função seja de fato tão pequena quanto a do exemplo acima, é provável que seja melhor fazer o rebase dela para a ramificação main
e realizar um merge de avanço rápido. Assim, você evita que os commits de merge supérfluo se acumulem no histórico do projeto.
Resolução de conflitos
Se as duas ramificações que você está tentando mesclar alterarem a mesma parte do mesmo arquivo, o Git pode não conseguir decidir qual versão usar. Quando essa situação ocorre, ele para antes do commit de mesclagem para que você possa resolver os conflitos.
A parte boa do processo de mesclagem do Git é que ele usa o já conhecido fluxo de trabalho edit/stage/commit para resolver conflitos de mesclagem. Quando você encontra um conflito de mesclagem, executar o comando git status
vai exibir quais arquivos precisam ser resolvidos. Por exemplo, se ambos os branches modificaram a mesma sessão de hello.py
, você veria algo como o seguinte:
On branch main
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: hello.py
Como os conflitos são apresentados
Quando o Git encontra um conflito durante uma mesclagem, ele edita o conteúdo dos arquivos afetados com indicadores visuais que marcam os dois lados do conteúdo conflitante. Esses marcadores visuais são:<<<<<<<, =======, e>>>> >>>. É útil pesquisar esses indicadores em um projeto durante uma mesclagem para descobrir onde os conflitos precisam ser resolvidos.
here is some content not affected by the conflict
<<<<<<< main
this is conflicted text from main
=======
this is conflicted text from feature branch
>>>>>>> feature branch;
Em geral, o conteúdo antes do marcador =======
é o branch receptor e a parte seguinte é o branch que vai ser mesclado.
Após identificar as seções conflitantes, você pode corrigir a mesclagem como preferir. Quando você estiver pronto para concluir a mesclagem, tudo o que precisa fazer é executar git add
no(s) arquivo(s) conflitante(s) para dizer ao Git que eles foram resolvidos. Em seguida, você executa um git commit
normal para gerar o commit de mesclagem. É o mesmo processo de fazer o commit de um snapshot comum, o que significa que é fácil para desenvolvedores normais gerenciarem suas próprias mesclagens.
Observe que conflitos de mesclagem vão ocorrer apenas no caso da mesclagem de 3 vias. Não é possível ocorrerem alterações conflitantes em uma mesclagem de avanço rápido.
Resumo
Este documento é uma visão geral do comando git merge
. A mesclagem é um processo essencial ao trabalhar com o Git. Foi abordada a mecânica interna por trás da mesclagem e as diferenças entre uma mesclagem de avanço rápido e uma mesclagem verdadeira, a de três vias. Algumas das principais conclusões são:
1. A mesclagem do Git combina sequências de commits em um histórico unificado de commits.
2. Há duas maneiras principais do Git fazer a mesclagem: a de avanço rápido e a de três vias
3. O Git pode fazer a mesclagem automática dos commits, a menos que haja alterações que entrem em conflito em ambas as sequências de commit.
Este documento integrou e fez referência a outros comandos do Git, como: git branch, git pull e git fetch. Visite suas páginas correspondentes para obter mais informações.
Compartilhar este artigo
Próximo tópico
Leitura recomendada
Marque esses recursos para aprender sobre os tipos de equipes de DevOps ou para obter atualizações contínuas sobre DevOps na Atlassian.