Usando ramificações

Git merge

A 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 um único branch.

Observe que todos os comandos apresentados abaixo fazem a mesclagem para o branch atual. O branch atual vai ser atualizado para refletir a mesclagem, mas o branch alvo não vai sofrer alterações. Mais uma vez, isso significa que 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 múltiplas sequências de commits no 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. Uma vez que o Git encontra um commit base em comum, ele cria uma "confirmação de mesclagem" combinando as alterações de cada sequência de commit de mesclagem enfileirada.

Vamos supor que temos um novo recurso de branch que é baseado na branch principal. Agora, a gente quer mesclar este recurso no branch principal.

Executar este comando vai mesclar o recurso de branch especificado no branch atual, vamos supor que seja a principal. O Git vai determinar o algoritmo da mesclagem com agilidade (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 o HEAD está apontando para o branch receptor correto. Se necessário, execute git checkout para alterar para o branch receptor. No caso, vamos executar git checkout master.

Buscar os commits remotos mais recentes

Verifique se o branch receptor e o branch que vai ser mesclado estão atualizados com as alterações remotas mais recentes. Execute git fetch fazer o pull dos commits remotos mais recentes. Após a conclusão da busca, veja se o branch principal tem as atualizações mais recentes executando o 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

Uma mesclagem de avanço rápido pode ocorrer quando existe um caminho linear da ponta do branch atual até o branch alvo. Em vez de mesclar de fato os branches, tudo o que o Git precisa fazer para integrar os históricos é mover (ou seja, fazer o "avanço rápido") a ponta do branch atual até a ponta do branch alvo. Isto vai combinar os históricos eficiência, uma vez que todos os commits alcançáveis a partir do branch alvo estão agora disponíveis através do atual. Por exemplo, a mesclagem de avanço rápido de algum recurso para o branch principal pareceria 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 rebasing) para pequenos recursos ou resoluções de 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 das duas ramificações.

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.

 # Iniciar um novo recurso git checkout -b new-feature master # Editar alguns arquivos git add  git commit -m "Start a feature" # Editar alguns arquivos git add  git commit -m "Finish a feature" # Mesclar com a branch do novo recurso git checkout master 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 recursos de maior execução.

Observe também que o Git não deve reclamar sobre o git branch -d, uma vez que o novo recurso está agora acessível do branch 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  

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 uma mesclagem de 3 vias pois o branch principal progride enquanto o recurso está em progresso. Este é um cenário comum para recursos grandes ou para quando muitos desenvolvedores estão trabalhando no projeto ao mesmo tempo.

 Start a new feature git checkout -b new-feature master # Editar alguns arquivos git add  git commit -m "Start a feature" # Editar alguns arquivos git add  git commit -m "Finish a feature" # Desenvolver a branch principal git checkout master # Editar alguns arquivos git add  git commit -m "Make some super-stable changes to master" # Mesclar com a branch do novo recurso git merge new-feature git branch -d new-feature

Observe que é impossível para o Git realizar uma mesclagem de avanço rápido, pois não há como mover o branch principal até o novo recurso sem retroceder.

Para a maioria dos fluxos de trabalho, o novo recurso seria um recurso muito maior, que levou muito tempo para ser desenvolvido, o que explicaria os novos commits aparecendo no branch principal enquanto isso. Se o seu branch de recurso fosse de fato tão pequeno quanto o do exemplo acima, é provável que fosse melhor fazer o rebase dele para o branch principal e fazer uma mesclagem de avanço rápido para evitar que os commits de mesclagem supérfluas 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 ambas as ramificações modificaram a mesma sessão de hello.py, você veria algo como o seguinte:

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

Como os conflitos são apresentados

Quando o Git encontrar um conflito durante uma mesclagem, ele vai editar o conteúdo dos arquivos afetados com indicações visuais, marcando ambos os lados do conteúdo em conflito. Estas marcações visuais são: <<<<<<<, =======, e >>>>>>>. É útil pesquisar um projeto por estes indicadores durante uma mesclagem para encontrar onde conflitos precisam ser resolvidos.

 aqui está um conteúdo não afetado pelo conflito <<<<<<< master aqui está um texto conflitante do branch principal ======= aqui está um texto conflitante da branch de recurso >>>>>>> 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, sem nenhuma alteração, o que significa que é fácil para desenvolvedores normais gerenciar 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, de 3 vias. Alguns dos principais aprendizados são:

  1. A mesclagem do Git combina sequências de commits no histórico unificado de commits.
  2. Existem dois modos principais de mesclagens do Git: avanço rápido e 3 vias
  3. O Git pode mesclar com agilidade os commits, a não ser que existam mudanças que conflitem com ambas as sequências de commits.

Este documento integrou e fez referência a outros comandos Git, como: git branch, git pull e git fetch. Visite suas páginas correspondentes para obter mais informações.

Pronto para tentar um branch?

Tente este tutorial interativo.

Comece agora mesmo