25. Resolvendo conflitos

Metas

  • Aprender a resolver conflitos de merge.

01 Fazer merge do branch main com o style

Vamos voltar ao ramo style e mesclar todas as alterações recentes do main.

Execute

git switch style
git merge main

Resultado

$ git switch style
Switched to branch 'style'
$ git merge main
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Parece que estamos em um conflito. Nenhuma surpresa! Vamos ver o que o Git tem a dizer sobre isso:

Execute

git status

Resultado

$ git status
On branch style
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

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

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

Se você abrir o index.html, verá:

Arquivo: index.html

<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
  <head>
<<<<<<< HEAD:index.html
    <link type="text/css" rel="stylesheet" media="all" href="style.css" />
=======
    <title>Hello World Page</title>
>>>>>>> main:hello.html
  </head>
  <body>
    <h1>Hello, World!</h1>
    <p>Let's learn Git together.</p>
  </body>
</html>

A parte entre <<<<<<< e >>>>>>> é o conflito. A seção na parte superior corresponde à ramificação style, que é a ramificação atual (ou HEAD) do repositório. A parte inferior corresponde às alterações da ramificação main. O Git não consegue decidir quais alterações aplicar, portanto, ele solicita que você resolva o conflito manualmente. Você pode deixar as alterações do ramo style ou do main, ou pode combiná-las da maneira que desejar. Você também pode fazer qualquer outra alteração no arquivo.

A propósito, você notou que nossa segunda alteração, a tag <p>, não faz parte do conflito? Isso se deve ao fato de o Git ter conseguido mesclá-la automaticamente.

02 Abortando a fusão

Antes de começarmos a resolver nosso conflito, deixe-me mencionar que ir direto para a resolução do conflito nem sempre é o melhor caminho a seguir. O conflito pode ser causado por alterações das quais você não está ciente. Ou as alterações são grandes demais para serem resolvidas imediatamente. Por esse motivo, o Git permite que você aborte a mesclagem e volte ao estado anterior à mesclagem. Para fazer isso, você pode usar o comando git merge --abort, conforme sugerido pelo comando status que executamos anteriormente.

Execute

git merge --abort
git status

Resultado

$ git merge --abort
$ git status
On branch style
nothing to commit, working tree clean

03 Resolução do conflito

Depois de meditar um pouco, estamos prontos para lidar com o conflito. Vamos executar a mesclagem novamente.

Execute

git merge main

Para resolver o conflito, precisamos editar o arquivo até o estado em que estamos satisfeitos e, em seguida, fazer o commit como de costume. No nosso caso, combinaremos as alterações de ambas as ramificações. Portanto, editamos o arquivo para o seguinte estado:

Arquivo: index.html

<!-- Author: Alexander Shvets (alex@githowto.com) -->
<html>
  <head>
    <title>Hello World Page</title>
    <link type="text/css" rel="stylesheet" media="all" href="style.css" />
  </head>
  <body>
    <h1>Hello, World!</h1>
    <p>Let's learn Git together.</p>
  </body>
</html>

04 Faça o commit do conflito resolvido

Execute

git add index.html
git commit -m "Resolved merge conflict"
git status
git log --all --graph

Resultado

$ git add index.html
$ git commit -m "Resolved merge conflict"
[style 79ac6fa] Resolved merge conflict

Vamos examinar o estado atual do nosso repositório e nos certificar de que tudo está bem:

Execute

git status
git log --all --graph

Resultado

$ git status
On branch style
nothing to commit, working tree clean
$ git log --all --graph
*   79ac6fa 2023-11-28 | Resolved merge conflict (HEAD -> style) [Alexander Shvets]
|\  
| * 85c14e9 2023-11-28 | Added meta title (main) [Alexander Shvets]
* | a33deed 2023-11-28 | Merge branch 'main' into style [Alexander Shvets]
|\| 
| * ee16740 2023-11-28 | Added README [Alexander Shvets]
* | 0ee0113 2023-11-28 | Renamed hello.html; moved style.css [Alexander Shvets]
* | 903eb1d 2023-11-28 | Included stylesheet into hello.html [Alexander Shvets]
* | 555372e 2023-11-28 | Added css stylesheet [Alexander Shvets]
|/  
* 9288a33 2023-11-28 | Added copyright statement with email [Alexander Shvets]
* b7614c1 2023-11-28 | Added HTML header (tag: v1) [Alexander Shvets]
* 46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
* 78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
* 5836970 2023-11-28 | Initial commit [Alexander Shvets]

05 Merging avançado

Git não tem ferramentas gráficas de merging, mas aceita qualquer ferramenta de merge produzida por terceiros. (leia mais sobre essas ferramentas no StackOverflow.)

Ao trabalhar com código de programação em um ambiente de desenvolvimento integrado (IDE) moderno, como o Visual Studio ou o IntelliJ IDEA, você provavelmente usará uma ferramenta de mesclagem integrada. Por exemplo, veja como é a resolução de conflitos no IntelliJ IDEA:

IntelliJ IDEA merge tool