25. Resolving conflicts

Goals

  • Learn to resolve merging conflicts.

01 Merge the main branch into the style branch

Let us return to the style branch and merge in all the recent changes from the main.

Run

git switch style
git merge main

Result

$ 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.

It seems that we have a conflict. No surprise here! Let us see what Git has to say about it:

Run

git status

Result

$ 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")

If you open the index.html you will see:

File: 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>

The section between <<<<<<< and >>>>>>> represents the conflict. The upper section corresponds to the style branch, which is the current branch (or HEAD) of the repository. The lower section represents changes from the main branch. Git is unable to determine which changes to apply, hence it requires manual conflict resolution. You are free to retain changes from either the style or main branch, combine them, or make any other modifications to the file.

Interestingly, our second change, the <p> tag, is not part of the conflict. Git has managed to merge it automatically.

02 Aborting merge

Jumping straight to the conflict resolution may not be a best strategy. The conflict may be caused by the changes you are unaware of. Or the changes are too significant to address right away. For this reason, Git allows you to abort the merge and return to the state before the merge. To do that, you can use the git merge --abort command, as suggested by status command we ran earlier.

Run

git merge --abort
git status

Result

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

03 Resolving the conflict

After some meditation, we are ready to handle the conflict. Let us rerun the merge.

Run

git merge main

To resolve the conflict, we need to edit the file to the state we're happy with and then commit it as usual. In our case, we will combine the changes from both branches. So, we edit the file to the following state:

File: 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 Commit the resolved conflict

Run

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

Result

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

Let us look at the current state of our repository and make sure that everything is okay:

Run

git status
git log --all --graph

Result

$ 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]

04 Advanced Merging

Git has no graphical merging tools, but it will accept any third-party merge tool (read more about such tools on StackOverflow).

When working with programming code in a modern integrated development environment (IDE), such as Visual Studio or IntelliJ IDEA, you will most likely use a built-in merge tool. For example, here is how the conflict looks like in IntelliJ IDEA:

IntelliJ IDEA merge tool