Conflito de merge
- Em inglês: merge conflict
Um conflito de merge acontece quando o Git está combinando alterações e não consegue decidir com segurança qual versão de um arquivo deve prevalecer.
Apesar do nome, conflitos de merge podem aparecer em várias operações do Git, não só quando você executa git merge. Eles podem acontecer quando você:
- Mergeia uma branch em outra com
git merge. - Reaplica commits em cima de outra branch com
git rebase. - Puxa alterações remotas com
git pull, porque o pull normalmente faz um merge ou um rebase depois do fetch. - Aplica um commit em outro lugar com
git cherry-pick. - Desfaz um commit com
git revert, se a alteração inversa não se aplica de forma limpa. - Reaplica alterações guardadas no stash com
git stash popougit stash apply.
Os conflitos costumam acontecer quando duas branches alteraram as mesmas linhas de um arquivo, ou quando uma branch alterou um arquivo que outra branch excluiu ou renomeou. O Git interrompe a operação para que você tome a decisão final.
Erros relacionados, como "your local changes would be overwritten", não são exatamente a mesma coisa. Nesse caso, o Git normalmente para antes de iniciar a operação, para que você salve ou descarte suas alterações locais primeiro.
Quando um arquivo de texto tem um conflito de conteúdo, o Git escreve marcadores de conflito dentro do arquivo:
<<<<<<< HEAD
a versão da sua branch atual
=======
a versão que o Git está tentando trazer
>>>>>>> feature-branchA parte acima de ======= é um lado do conflito. A parte abaixo é o outro lado. Seu trabalho é editar o arquivo até chegar à versão final que você realmente quer e depois remover todos os marcadores de conflito.
Ours e theirs
O Git e os editores de código às vezes rotulam os dois lados de um conflito como ours e theirs. Algumas ferramentas usam rótulos como current e incoming para a mesma ideia. Cuidado com esses nomes: eles descrevem os lados da operação atual do Git, não necessariamente "meu trabalho" e "o trabalho de outra pessoa".
Em um merge comum, o significado costuma ser intuitivo:
git switch maingit merge feature
- Ours é a
main, a branch em que você estava antes de começar o merge. - Theirs é a
feature, a branch que está sendo mergeada.
Durante um rebase, os rótulos podem parecer invertidos:
git switch featuregit rebase main
O Git coloca temporariamente o seu trabalho em cima da main. Se um conflito acontece enquanto o Git está reaplicando um commit da feature:
- Ours é o lado da
main, porque essa é a base que está em checkout naquele momento do rebase. - Theirs é o commit da
featureque está sendo reaplicado.
Isso significa que escolher ours durante um rebase pode descartar a alteração da branch que você considera "sua". Comandos como git restore --ours path/to/file e git restore --theirs path/to/file escolhem um lado inteiro de um arquivo em conflito, então só use esses comandos quando tiver certeza de qual lado o Git quer dizer na operação atual.
Como resolver um conflito
O fluxo habitual é:
- Execute
git statuspara ver quais arquivos estão em conflito. - Abra cada arquivo em conflito e edite o conteúdo até chegar à versão final correta.
- Remova as linhas de marcadores
<<<<<<<,=======e>>>>>>>. - Adicione os arquivos resolvidos ao stage com
git add. - Continue a operação: commite o merge, execute
git merge --continueou executegit rebase --continue, dependendo do que o Git indicar.
O Git não verifica se a sua resolução está logicamente correta. Depois que você adiciona o arquivo ao stage, o Git trata aquele conteúdo como a resposta. Leia o resultado antes de continuar.
Se o conflito apareceu de forma inesperada e você não está em condições de resolvê-lo agora, muitas vezes você pode voltar ao estado anterior com git merge --abort ou git rebase --abort.
.gitignoregit checkoutgit configgit taggit worktree