Você tenta juntar duas branches e o Git responde algo como “CONFLICT (content): Merge conflict in arquivo.txt. Automatic merge failed”. A primeira reação é achar que quebrou o projeto. Não quebrou: o Git juntou tudo o que conseguiu e parou nos pontos onde precisa da sua decisão.
Se os conceitos de branch e merge ainda são novos, veja Git no dia a dia antes de continuar.
Por que o conflito acontece
O Git é inteligente para juntar mudanças que não se tocam. Se uma branch alterou o início de um arquivo e a outra o final, ele une as duas sem perguntar. O conflito surge quando:
- as duas branches mudaram as mesmas linhas de forma diferente;
- uma branch apagou um arquivo que a outra modificou;
- as duas criaram um arquivo com o mesmo nome e conteúdos diferentes.
Nesses casos, o Git não tem como adivinhar o que você quer e deixa o arquivo marcado.
Como o arquivo fica
Ao abrir o arquivo com conflito, você verá marcas inseridas pelo Git. Elas têm este formato:
- uma linha que começa com sete sinais de menor (<<<<<<<) seguida do nome da sua branch atual;
- o trecho como está na sua branch;
- uma linha com sete sinais de igual (=======) separando as duas versões;
- o trecho como está na outra branch;
- uma linha com sete sinais de maior (>>>>>>>) seguida do nome da outra branch.
Tudo entre a primeira marca e a linha dos iguais é a sua versão. Tudo entre os iguais e a última marca é a versão que está chegando. Seu trabalho é decidir o que fica.
Passo a passo para resolver
- Veja quais arquivos estão em conflito com git status. Eles aparecem como “both modified” (ambos modificados) ou sob a seção de caminhos não mesclados.
- Abra cada arquivo em um editor. Editores de código como o VS Code destacam os conflitos e oferecem botões para aceitar a versão atual, a que chega ou as duas (veja configurar o VS Code).
- Decida o resultado final. Há três saídas:
- manter só a sua versão;
- manter só a versão da outra branch;
- combinar as duas, escrevendo um texto que contenha o que importa de cada uma.
- Apague as marcas (<<<<<<<, ======= e >>>>>>>). O arquivo final não pode conter nenhuma delas.
- Teste. Rode o projeto ou os testes. Um conflito mal resolvido pode gerar código que nem roda.
- Marque como resolvido com git add nome-do-arquivo.
- Conclua o merge com git commit. O Git já sugere uma mensagem padrão que você pode aceitar.
Quando você quer desistir
Se o conflito for grande demais, ou você percebeu que juntou a branch errada, dá para cancelar: git merge --abort. O repositório volta ao estado de antes do merge, sem perder nada. Depois, converse com quem fez a outra mudança ou refaça o merge com mais calma.
Se você estava atualizando sua branch com git pull e deu conflito, o raciocínio é o mesmo: resolver os arquivos, git add e commit. Se estiver usando rebase em vez de merge, os comandos de continuação e cancelamento são outros (rebase --continue e rebase --abort). Para quem está começando, o merge costuma ser mais fácil de entender.
Como decidir qual versão manter
Nem sempre a escolha é óbvia. Algumas perguntas ajudam:
- O que cada lado queria fazer? Veja as mensagens de commit com git log.
- As duas mudanças são compatíveis? Muitas vezes dá para ficar com as duas.
- Qual é a mais recente, ou a que tem a regra de negócio correta?
- Existe teste que valide o comportamento esperado?
Em equipe, o melhor é falar com a pessoa que fez a outra alteração. Em dúvida, uma conversa de dois minutos evita horas de retrabalho.
E quando o conflito é em arquivo de dependências
Arquivos gerados automaticamente, como os de travamento de versões de pacotes, costumam gerar conflitos longos. Em vez de editar à mão, a prática comum é escolher uma versão e depois pedir ao gerenciador de pacotes que regenere o arquivo. Confira a documentação da ferramenta que usa.
Ferramentas que ajudam a resolver
Resolver tudo à mão no texto é possível, mas há recursos que facilitam:
- Editores de código com destaque visual: mostram as duas versões lado a lado e oferecem botões como aceitar a mudança atual, a recebida ou ambas.
- Ferramentas de comparação (diff e merge tools): o Git pode abrir uma delas com o comando git mergetool, se estiver configurada.
- Interfaces do GitHub: para conflitos simples em propostas de mudança, o site oferece um editor para resolver no navegador.
Qualquer que seja a ferramenta, o resultado precisa ser o mesmo: arquivo coerente, sem marcas, testado e adicionado ao commit. Em conflitos grandes, resolva um arquivo por vez e vá confirmando o que já está pronto.
Como reduzir a frequência de conflitos
- Branches de vida curta. Quanto mais tempo uma branch fica isolada, mais ela se afasta da principal.
- Atualize sua branch com frequência. Traga as novidades da principal para a sua com regularidade, resolvendo conflitos pequenos no caminho.
- Commits pequenos e focados.
- Combine a divisão do trabalho: evite que duas pessoas editem o mesmo arquivo grande ao mesmo tempo.
- Evite reformatações em massa misturadas com mudanças de lógica.
Conflitos fazem parte de qualquer projeto com mais de uma linha de trabalho. Quando você os encara como uma pergunta do Git, “qual das versões vale?”, deixam de ser um susto e viram uma tarefa de dez minutos. Para ampliar o domínio da ferramenta, volte a Git e GitHub para iniciantes.