GitMuninnGitMuninn
← Voltar ao blog

Como resolver conflitos de merge no Git sem medo

Por que o conflito acontece, como ler os marcadores, o passo a passo para resolver em merge e em rebase, ferramentas que ajudam e hábitos para ter menos conflitos.

Você roda git merge e o terminal responde: CONFLICT (content): Merge conflict in src/api.ts. Calma. Não é um erro. É o Git pedindo uma decisão que ele não consegue tomar sozinho.

Neste guia você vai entender por que o conflito acontece, como ler o que o Git escreveu no arquivo, como resolver em um merge e em um rebase, quais ferramentas ajudam e o que fazer no dia a dia para ter menos conflitos.

Por que o conflito acontece

O Git junta sozinho as mudanças que estão em partes diferentes de um arquivo. Se você mudou a linha 10 e um colega mudou a linha 80, o merge acontece sem perguntar nada.

O conflito aparece em três situações:

  • Os dois branches mudaram as mesmas linhas, ou linhas muito próximas.
  • Um lado apagou um arquivo que o outro editou (deleted by them ou deleted by us).
  • Os dois lados criaram ou renomearam o mesmo arquivo de formas diferentes.

Nesses casos não existe resposta automática certa. Alguém que conhece o código precisa olhar e decidir.

Como ler os marcadores

Dentro do arquivo, o Git marca o trecho em disputa assim:

<<<<<<< HEAD
const timeout = 30;
=======
const timeout = 60;
>>>>>>> feature/retry
  • Entre <<<<<<< HEAD e ======= está o seu lado, ou seja, o branch em que você está.
  • Entre ======= e >>>>>>> feature/retry está o lado que chegou com o merge.
  • A sua tarefa é deixar só o resultado final: um dos lados, o outro, ou uma combinação dos dois. E apagar os marcadores.

Uma dica que ajuda muito: ative o estilo zdiff3. Com ele, o Git mostra também como o trecho era antes dos dois lados mudarem, o que deixa claro o que cada um quis fazer.

git config --global merge.conflictStyle zdiff3
<<<<<<< HEAD
const timeout = 30;
||||||| base
const timeout = 10;
=======
const timeout = 60;
>>>>>>> feature/retry

Agora dá para ver que o valor original era 10. Você subiu para 30 e o colega para 60. A decisão fica muito mais fácil.

Passo a passo para resolver um merge

  1. Rode git status para ver os arquivos em conflito. Eles aparecem como both modified.
  2. Abra cada arquivo, decida cada bloco e remova os marcadores.
  3. Compile e rode os testes. Um merge sem marcadores ainda pode quebrar o código, por exemplo quando um lado renomeou uma função que o outro passou a usar.
  4. Marque cada arquivo como resolvido com git add <arquivo>.
  5. Conclua com git commit. O Git já sugere uma mensagem de merge.

Se o arquivo inteiro deve ficar como está em um dos lados, não precisa editar bloco a bloco:

git checkout --ours src/api.ts     # fica com o seu lado
git checkout --theirs src/api.ts   # fica com o lado que chegou
git add src/api.ts

Se algo sair do controle, git merge --abort volta tudo para o estado de antes do merge. Você pode recomeçar com calma.

Conflitos durante um rebase

No rebase, o Git reaplica os seus commits, um por um, em cima de outro branch. Por isso o conflito pode aparecer mais de uma vez, uma para cada commit que toca as mesmas linhas.

O fluxo é parecido, com uma diferença importante: no rebase, ours e theirs se invertem. --ours passa a ser o branch de destino, por exemplo a main, e --theirs é o commit seu que está sendo reaplicado.

  1. Resolva os arquivos do commit atual e rode git add.
  2. Continue com git rebase --continue.
  3. Repita até o rebase terminar.
  4. Se preferir desistir, git rebase --abort volta tudo como estava.

Ferramentas que ajudam

  • git mergetool abre uma ferramenta visual configurada, como o VS Code, o Meld ou o KDiff3.
  • git log --merge -p <arquivo> mostra só os commits dos dois lados que tocaram o arquivo em conflito.
  • git rerere grava como você resolveu um conflito e reaplica a mesma solução se ele aparecer de novo. Ative com git config --global rerere.enabled true.
  • git diff durante o conflito mostra só os trechos ainda não resolvidos.

Como ter menos conflitos

  • Traga a main para o seu branch com frequência, não só no final.
  • Prefira branches curtos, que vivem dias e não semanas.
  • Faça commits pequenos e focados em uma mudança.
  • Combine um formatador de código com o time, para espaços e quebras de linha não virarem conflito.
  • Evite mover um arquivo e editar o conteúdo dele no mesmo commit.
  • Converse antes de mexer em arquivos que todo mundo edita, como rotas, configurações e listas de dependências.

Resolvendo conflitos no GitMuninn

No GitMuninn, o conflito aparece bloco a bloco. Para cada bloco você escolhe o seu lado, o lado que chegou ou os dois, e salva quando o arquivo estiver resolvido, sem caçar marcadores. O grafo mostra de onde veio cada branch, o que ajuda a entender a mudança antes de decidir. Isso está incluído no plano Grátis.

Veja seus branches no GitMuninn.

Entre na lista de lançamento e ganhe um cupom de 50% de desconto por 12 meses.

Plano de interesse

Para macOS, Windows e Linux. Sem spam, saia quando quiser.