Resolver conflitos de fusão em Git

Azhar Bashir Khan 25 dezembro 2021
Resolver conflitos de fusão em Git

Neste tutorial, demonstraremos como resolver conflitos que surgem na fusão de duas ramificações no Git.

Normalmente, o trabalho geralmente é feito nos mesmos arquivos por diferentes membros da equipe em um ambiente de equipe colaborativa. Por exemplo, um membro da equipe trabalhando no desenvolvimento de algum recurso pode editar o arquivo README para fornecer informações sobre o recurso desenvolvido.

Outro membro da equipe trabalhando na correção de bugs pode adicionar informações sobre os bugs corrigidos no mesmo arquivo README. Eles podem estar trabalhando em diferentes branches e enviando suas alterações em seus respectivos branches.

De vez em quando, diferentes branches precisam ser mesclados para fornecer uma construção coesa. Portanto, esta operação causará um conflito de mesclagem quando os mesmos arquivos forem atualizados em diferentes ramos.

Em seguida, é necessário resolver os conflitos e mesclar as mudanças. Vamos agora ilustrar isso com um exemplo.

Resolvendo os conflitos decorrentes da fusão de duas filiais com git mergetool

Antes de resolver conflitos de mesclagem, devemos configurar a ferramenta diff usada pelo Git da seguinte maneira.

$ git config merge.tool meld
$ git config merge.conflictstyle diff3
$ git config mergetool.prompt false

Os comandos acima definem meld como a ferramenta de comparação padrão. Além disso, configuramos o conflictstyle para diff3 (ou seja); isso configura a ferramenta diff para mostrar o ancestral comum para ambos os arquivos (um da ramificação atual e aquele na ramificação a partir do qual se fundir).

Para ver as diferentes ferramentas diff suportadas, execute o seguinte comando.

$ git mergetool --tool-help

Agora, começamos com o exemplo para demonstrar como resolver conflitos. Digamos que temos dois ramos da seguinte maneira.

$ git branch
* main
  feature1

A primeira ramificação é a ramificação main e a segunda é uma ramificação de desenvolvimento de recursos chamada feature1.

Temos um arquivo README.md com o conteúdo a seguir no ramo main.

$ cat README.md
# Upwork
Upwork projects

Conforme mostrado acima, estamos atualmente no ramo main. Então, mudamos para o ramo feature1.

$ git checkout feature1
Switched to branch 'feature1'

$ git branch
  main
* feature1

Atualizamos o README.md e imprimimos seu conteúdo como segue.

$ cat README.md
This is conflicting branch line.

Agora, iremos fundir o branch main com o branch feature1 para obter as últimas mudanças naquele branch.

Durante a fusão, o Git mostra os conflitos de fusão da seguinte maneira.

$ git merge main
Auto-merging README.md
CONFLICT (add/add): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

Podemos obter mais informações sobre o conflito da seguinte maneira.

$ git status
On branch feature1
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both added:      README.md

no changes added to commit (use "git add" and/or "git commit -a")

Iremos agora imprimir o conteúdo do arquivo README.md, que contém o conflito.

$ cat README.md 
<<<<<<< HEAD
This is conflicting branch line.

||||||| merged common ancestors
=======
# Upwork
Upwork projects
>>>>>>> main

O arquivo mostra vários símbolos agora.

E os símbolos <<<<<<< seguidos por HEAD é um apelido para o branch atual. Isso indica o início das edições nesta seção.

Os símbolos ======= mostram o fim das revisões dentro do branch atual e o início das edições dentro de um novo.

Os símbolos >>>>>>> seguidos pelo nome do ramo remoto viz. main, mostra onde ocorreu a tentativa de fusão.

Agora, vamos usar mergetool para resolver os conflitos.

$ git mergetool
Merging:
README.md

Normal merge conflict for 'README.md':
  {local}: created file
  {remote}: created file

Isso iniciará meld (já que definimos isso como a ferramenta diff padrão). Por favor, veja a imagem abaixo.

git-mergetool-meld1

O painel esquerdo mostra as edições do arquivo README.md feitas no branch local. O painel do meio contém o resultado das mudanças feitas para resolver o conflito. O painel direito mostra as edições feitas no ramo remoto vizinho main (i.e.) o ramo que queremos fundir.

Podemos escolher manter as alterações locais e remotas ou qualquer uma delas. Escolheremos manter as alterações do branch remoto da seguinte maneira.

git-mergetool-meld2

Em seguida, salvaremos e sairemos da ferramenta meld.

Iremos imprimir o arquivo README.md e ver a atualização.

$ cat README.md
# Upwork
Upwork projects

Agora vamos enviar as alterações para o Git.

$ git commit -m "merged from main"
[feature1 3c39d7b] merged from main

Iremos agora executar o comando git diff para verificar se há conflitos entre os ramos feature1 e main.

$ git diff feature1 main

Verificaremos o status do ramo feature1.

$ git status
On branch feature1

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	README.md.orig

Ele mostra um arquivo, README.md.orig, que foi criado pelo mergetool durante a fusão.

Execute o seguinte comando para removê-lo:

$ git clean -f

Assim, resolvemos com sucesso os conflitos ao mesclar duas ramificações usando o mergetool do Git.

Artigo relacionado - Git Merge