git merge

Branches e merge

Juntar dois ou mais históricos de desenvolvimento


O comando 'git merge' incorpora na branch atual as mudanças dos commits indicados (desde que os históricos se separaram da branch atual). O Git faz um merge “fast-forward” quando possível (quando a branch atual é ancestral da branch mesclada) ou cria um “commit de merge” quando os históricos divergiram. Se houver conflitos entre as branches, o Git para e pede que você os resolva antes de concluir o merge.

Sinopse

git merge [--no-ff | --ff-only] [--squash] [--no-commit] [-m <msg>] [--allow-unrelated-histories] [<commit>...]
git merge (--continue | --abort | --quit)
[ ] opcional| ou<arg> valor a substituir... repetível--flag opção

Opções

Clique em uma opção para expandir

Iniciante (5)

Criar um commit de merge mesmo quando o merge poderia ser um fast-forward. Preserva o histórico da branch e deixa claro onde o trabalho da funcionalidade começou e terminou.

Quando necessárioSempre registra um commit de merge — uma convenção da equipe

Exemplo

git merge --no-ff feature

Recusar o merge a menos que o HEAD atual já esteja atualizado ou que o merge possa ser resolvido como fast-forward. Evita commits de merge acidentais.

RecomendadoNunca cria commits de merge inesperados; falha se os históricos divergiram

Exemplo

git merge --ff-only feature

Cancelar o processo de resolução de conflitos em andamento e voltar o repositório ao estado anterior ao merge. Use quando quiser cancelar um merge com conflito.

RecomendadoSai com segurança de um merge com conflito e volta ao estado anterior

Exemplo

git merge --abort

Depois de resolver os conflitos, concluir o merge. Equivale a rodar git commit após resolver os conflitos.

RecomendadoConclui o merge depois de resolver e preparar os conflitos

Exemplo

git merge --continue

Definir uma mensagem personalizada para o commit de merge. Não força um commit de merge: no fast-forward a mensagem é ignorada (combine com --no-ff para sempre ter um).

Quando necessárioMensagem própria para o commit de merge; ignorada quando o merge é fast-forward

Exemplo

git merge -m "Integrate login feature" feature

Intermediário (2)

Juntar todos os commits da branch mesclada em um único conjunto de mudanças preparadas. Não cria commit nem registra merge (sem MERGE_HEAD) - você faz o commit à mão, e o resultado é um commit comum com um único pai.

Quando necessárioUm commit limpo, mas não um merge de verdade; a branch precisa de -D depois

Exemplo

git merge --squash feature

Fazer o merge, mas parar antes de criar o commit. Permite inspecionar e modificar o resultado antes do commit. Um fast-forward ainda acontece; adicione --no-ff para garantir a parada.

Quando necessárioConfira o resultado antes do commit; combine com --no-ff

Exemplo

git merge --no-commit feature

Avançado (1)

Permitir mesclar históricos sem ancestral comum. Útil para juntar dois repositórios ou projetos separados.

Quando necessárioSó para unir projetos separados de propósito

Exemplo

git merge --allow-unrelated-histories other-project/main

Escolhendo a opção certa

Estratégias de merge

Como controlar o tipo de merge que o Git faz

ComandoCria commit de mergePreserva o históricoIdeal para
git merge (default)Se divergiramSimIntegração normal de funcionalidade
git merge --no-ffSempreSimDocumentar merges de funcionalidades
git merge --ff-onlyNuncaSó linearGarantir um histórico limpo
git merge --squashNão (commit comum)Não (achatado)Branch main limpa

Lidar com conflitos

O que fazer quando um merge tem conflitos

ComandoAçãoMantém o trabalhoQuando usar
(resolve manually)Editar arquivos, git addSimPrecisa de partes dos dois lados
--continueConcluir o mergeSimDepois de resolver os conflitos
--abortCancelar o mergeEstado anterior ao mergeNão está pronto para resolver agora
checkout --ours/--theirsEscolher um ladoUma versão sóUm lado está claramente certo

merge ou rebase

Dois jeitos de integrar mudanças - com prós e contras diferentes

ComandoHistóricoResolução de conflitosIdeal para
git mergePreserva todos os commitsUma vezBranches compartilhadas, PRs
git rebaseReescreve de forma linearPor commitLimpeza local, branches privadas
git merge --squashUm só commitUma vezFuncionalidade com histórico bagunçado

Controlar o commit

Opções para personalizar o commit de merge

ComandoFaz commit automaticamenteCaso de uso
git merge featureSim (se não houver conflitos)Merge padrão
git merge --no-commitNão (preparado)Revisar antes do commit
git merge -m "msg"Sim (ignorado no fast-forward)Commits de merge descritivos
git merge --squashNão (precisa fazer commit)Juntar todos os commits em um

Exemplos de fluxos de trabalho

1
git checkout main

Trocar para a branch main

2
git pull origin main

Pegar as mudanças mais recentes do remoto

3
git merge --no-ff feature-branch

Mesclar a funcionalidade com um commit de merge para o histórico

4
git push origin main

Enviar as mudanças mescladas para o remoto

5
git branch -d feature-branch

Excluir a branch de funcionalidade mesclada

1
git merge feature

Tentar o merge (aparecem conflitos)

2
git status

Ver quais arquivos têm conflitos

3
(edit conflicted files)

Procurar os marcadores <<<<<<< e resolver à mão

4
git add <resolved-files>

Preparar os arquivos resolvidos

5
git merge --continue

Concluir o merge com um commit

1
git checkout main

Trocar para a branch main

2
git merge --squash feature-branch

Juntar todos os commits em mudanças preparadas

3
git commit -m "Add feature X"

Criar um único commit limpo com todas as mudanças

4
git branch -D feature-branch

Forçar a exclusão da branch de funcionalidade

1
git merge feature

Começar o merge (surgem problemas)

2
git status

Ver o estado com conflitos

3
git merge --abort

Cancelar e voltar ao estado anterior ao merge

4
git status

Confirmar que voltou a um estado limpo

Solução de problemas

CONFLICT (content): Merge conflict in file.js

Causa: As duas branches modificaram as mesmas linhas do arquivo

Abra o arquivo, procure os marcadores <<<<<<<, resolva e depois git add e git merge --continue

fatal: refusing to merge unrelated histories

Causa: As branches não têm ancestral comum (repositórios separados)

Use git merge --allow-unrelated-histories se quiser mesmo juntar projetos separados

Already up to date

Causa: A branch que você está mesclando já está incluída na branch atual

Nada a fazer - a sua branch já contém todos os commits da outra

error: Your local changes to the following files would be overwritten by merge

Causa: Você tem mudanças sem commit que conflitam com o merge

Faça commit das mudanças, guarde-as com stash (git stash) ou descarte-as antes do merge

O merge foi feito, mas eu queria revisar antes

Causa: O Git fez o commit do merge automaticamente

Da próxima vez use --no-ff --no-commit. Para refazer: git reset --merge ORIG_HEAD e faça o merge de novo com --no-commit

Dicas e armadilhas

Boas práticas

  • ✓Sempre faça pull das mudanças mais recentes antes do merge para diminuir conflitos
  • ✓Use --no-ff em branches de funcionalidade para preservar o contexto do merge no histórico
  • ✓Escreva mensagens de merge descritivas que expliquem o que foi integrado
  • ✓Exclua as branches de funcionalidade depois do merge para manter o repositório limpo
  • ✓Teste o código depois do merge e antes do push para garantir que nada quebrou
  • ✓Use git merge --abort se não estiver pronto para resolver conflitos - não deixe um merge pela metade
  • ✓Em branches de longa duração, mescle a main na sua branch de funcionalidade de tempos em tempos para reduzir os conflitos do merge final

Erros comuns

  • ✗Fazer merge sem antes puxar as mudanças mais recentes do remoto. Sempre rode 'git pull' antes do merge para evitar conflitos.
  • ✗Preparar arquivos que ainda têm marcadores de conflito. O Git bloqueia commits enquanto há caminhos não mesclados, mas assim que você faz 'git add' em um arquivo ele entra no commit com os marcadores <<<<<<< do jeito que estão.
  • ✗Usar merges fast-forward em branches de funcionalidade perde o histórico da branch. Use '--no-ff' para preservar o contexto.
  • ✗Rodar 'git merge --abort' depois de resolver conflitos à mão perde todo o trabalho de resolução.
  • ✗Fazer merge na branch errada. Sempre confira com 'git branch' que você está na branch de destino certa antes do merge.

Perguntas frequentes

A:

O merge preserva o histórico e cria um commit de merge. O rebase reescreve o histórico para ficar linear. Use merge em branches compartilhadas e rebase para limpeza local.

A:

Use --no-ff ao mesclar branches de funcionalidade na main. Ele cria um commit de merge que registra quando a funcionalidade foi integrada, mesmo que o fast-forward fosse possível.

A:

Se não foi enviado: git reset --hard ORIG_HEAD (funciona também para fast-forwards; descarta mudanças sem commit). Se foi enviado: git revert -m 1 <merge-commit> para criar um commit novo que desfaz o merge.

A:

O fast-forward acontece quando a sua branch não tem commits novos desde o ponto de separação. O Git só avança o ponteiro em vez de criar um commit de merge.

A:

Abra os arquivos em conflito, procure os marcadores <<<<<<<, edite para ficar com o código que quer, remova os marcadores, depois faça git add nos arquivos e git merge --continue.

A:

O merge comum preserva todo o histórico de commits. O squash merge junta tudo em um único commit. Use squash quando a branch de funcionalidade tiver commits WIP bagunçados que você não quer na main.