Git Branches – Working with Branches – Part II (Merge Conflicts)

Git Merge Conflict Commit View

Branching sounds fine, but quite often so-called merge-conflicts occur, even in a single-user local-git-repository environment.

  • You created a feature branch A to develop a new feature. To implement the new feature you have to add and change a lot of the CSS in styles.css
  • Suddenly a bug appears on your website. To fix the bug, you also have to make changes in styles.css.

As we learned in the previous part of the tutorial this might not be a problem at all. This is what branching is for. You create a bugfix branch, fix the bug in styles.css, merge it into the MASTER and then deploy the MASTER into production.

So far this is not a problem. The problem will occur when you finished developing your new feature (that also affected styles.css) and merge it into the MASTER. So far changes from the bugfix were only merged with the MASTER. Branch A has no knowledge of this change. With the merge from Branch A into the MASTER, Git doesn’t know which is the correct version. Hence, Git responds with an error: merge-conflict. You have to resolve this conflict manually.

Git Branches - Merge Conflict
Git Branches – Merge Conflict
Git Merge Conflict Commit View
Git Merge Conflict Commit View

So after merging branch A into the MASTER using git merge A, Git will provide a message like

 ~/test/gitTest git merge A

error: Merging is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.

The whole merge process has put on halt. The data of branch A that was about to be merge is now in the Staging Area of the Master Branch (the Local Repository). You now have to manually resolve the conflict in styles.css manually.

When you edit styles.css you will discover that git added a few lines to the files (the version of styles.css that is currently in the Local Repository (HEAD) and the version with your changes in branch A:

/** Registration page */
.fieldError {
    border: 4px solid red;
<<<<<<< HEAD
    font-size: 12px;
=======
    font-weight: 20;
>>>>>>> A
}

You now have to manually the correct version of styles.css, e.g.

/** Registration page */
.fieldError {
    border: 4px solid red;
    font-size: 12px;
    font-weight: 20;
}

Then you have to add and commit the changes with git commit -a -m "conflict in styles.css resolved"

If you have a look at the Git-commit-history you will recognise that the master has also inherited the whole commit history

commit 31bf689a2f754f8154d66ae776fd80698a7c9174
Merge: 6186303 9c0a9b8
Author: chris <moser.christoph@gmx.de>
Date:   Fri Mar 23 12:43:01 2018 +0100

    conflict in styles.css resolved

commit 9c0a9b8c37d162207947f2a22e8bdaca89ec39c4
Author: chris <moser.christoph@gmx.de>
Date:   Fri Mar 23 12:27:16 2018 +0100

    feature A

commit 61863036a5d0f09f52e994be90a04527404f8646
Author: chris <moser.christoph@gmx.de>
Date:   Fri Mar 23 12:25:57 2018 +0100

    bug fixed in styles.css

...

Remarks

I haven’t covered all the possible things that can happen, e.g. try to make changes in branch A without adding/committing them and check-out the Bugfix branch and other things. Again, before using Git in a serious project, I highly recommend experimenting a bit more with this simple setting (one master, two branches, two text-files) to become more familiar with Git. When you are using Git to develop larger projects, you might have more than one merge-conflict at once. It can be difficult to keep track of all the changes. Hence, in this case, I recommend using Git GUI clients, such as SourceTree and others.
Chris