Merge Conflicts



The version control system's primary purpose is to manage the contributions of different developers. Merge conflicts occur when different developers update the same content. To solve this problem, developers should work in isolated branches. The git merge command is responsible for combining isolated branches and resolving any merge conflicts.


Understanding merge conflicts

Git makes merging and resolving conflicts easy comparing to other version control systems. In most cases, Git will figure out how to automatically integrate new changes.

Conflicts often occur when two developers edit the same lines in a file, or when one developer deletes a file while another was editing it.

In conflict cases, Git is unable to determine what is right automatically. The developer who is merging will be the only affected by conflicts; the other team members will be unaware of conflicts. Git will mark the file as being conflicted and stops the merging process. It is up to developers to resolve the conflict.


Types of merge conflicts

A conflict can occur at two separate points in the merging conflict at the start and during the merge process. In the following sections, we will see how to address each of these conflict cases.


Merge failure on start

Git fails to start a merge when there are pending changes in either the working directory or the staging area. Git fails to start a merge because pending changes could be overwritten by the commits that are being merged. This happens because of pending local changes, not because of the conflicts with other developers. To overcome the problem, the local state needs to be clean using the help of git checkout, git stash, git reset, git commit. The following error will be displayed when a merge failure on start occurs.

error: Entry '<fileName>' not uptodate. Cannot merge. (Changes in working directory)

Failure during the merge

The failure during a merge indicates a conflict between the current local branch and the branch being merged. Git will do its best to merge files, however for merge conflicts, it will need the user's intervention to resolve the conflicted files manually. The following error will be displayed when a merge failure occurs during a merge.

error: Entry '<fileName>' would be overwritten by merge. Cannot merge. (Changes in staging area)

Creating a merge conflict

The following example will simulate a merge conflict to understand how merge conflicts occur.

$ mkdir demo_dir 
$ cd demo_dir 
$ git init .
$ echo "some content" > demo.txt
$ git add demo.txt
$ git commit -am "initial commit"
[master 25bb47b] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 demo.tx

In the above example, we initiate a git repository on a "demo_dir" directory, we create a new "demo.txt" file with some content and add it to the commit history by committing it.

Now we have a new repository containing one master branch and a "demo.txt" file with some content. The next step is the creation of a new branch to use as a conflicting merge.

$ git checkout -b feature_to_merge
$ echo "some different content to merge later" > demo.txt
$ git commit -am "update the content of demo.txt to create a conflict"
[feature_to_merge 31a789a] initial commit
 1 file changed, 1 insertions(+), 0 deletions(-)

In the above commands, we create and checkout a new "feature_to_merge" branch, edit the content in "demo.txt", and commit the new content.

We have created a new "feature_to_merge" branch with a commit that overrides the content of "demo.txt" .

$ git checkout master 
Switched to branch 'master'
$ echo "more content to append" >> demo.txt 
$ git commit -am "append more content to demo.txt"
[master 95a4as4] added content to demo.txt 
1 file changed, 1 insertion(+)

In the above command, we check out the "master" branch, adding more content to "demo.txt", and committing the change. This puts our demo repository in a state where we have one commit in the master branch and one in the "feature_to_merge". Now let us run git merge feature_to_merge and see what happens.

$ git merge feature_to_merge
Auto-merging demo.txt 
CONFLICT (content): Merge conflict in demo.txt 
Automatic merge failed; fix conflicts and then commit the result.

As we can see, a conflict has occurred.


Identifying merge conflict

As we have already seen, Git output that a conflict has occurred. We can run the git status command to see the unmerged paths.

$ git status
On branch master 

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: demo.txt

The git status output shows that there are unmerged paths because of the conflict. The "demo.txt" appears in a modified state. Let us see the content of the "demo.txt" file with the cat command.

$ cat demo.txt
<<<<<<< HEAD
this is some content to mess with
content to append
=======
totally different content to merge later
>>>>>>> feature_to_merge

The content of "demo.txt" shows some new lines, <<<<<<< HEAD, =======, >>>>>>> feature_to_merge. These visual indicators are used by Git to marks the conflicted content.

The line ======= is the center of the conflict. The content between the center and the <<<<<<< HEAD line is the content existing in the current branch Master that the HEAD reference is pointing also. Otherwise, the content between the center and >>>>>>> feature_to_merge is the content existing in the merging branch.


Resolve merge conflicts using the command line

The way to resolve the merge conflict is to edit the conflicted file. Open the "demo.txt" file in the editor, remove all the marks, and choose which of the changes you want to keep the change from the master branch or the merge branch. If you want, you can keep both of the changes. The changed "demo.txt" file looks like the following:

this is some content to mess with
content to append
totally different content to merge later

Once you finished editing the conflicted file, use git add demo.txt to stage the new merge content, and to finish the merge, create a new commit by running the following command:

$ git commit -m "The conflict in demo.txt is resolved"

After this, Git will see the conflict has been resolved, and it will create a new merge commit to finalize the merge.


Git commands that help resolve merge conflicts

General tools

  • git status: It will help identify the conflicted files.

    $ git status 
    
  • git log --merge: The --merge with the git log command will generate a log with a list of commits that conflict between the merging branch.

    $ git log --merge
    
  • git diff: It helps find the differences between states of a repository or files. Running git diff can predict and prevent merge conflict before merging.

    $ git diff 
    

Tools to resolve merge failure on start

  • git checkout: It helps undo changes to files and changes branches.

    $ git checkout 
    
  • git reset --mixed: It helps undo changes to the working directory and staging area.

    $ git reset --mixed
    

Tools to resolve failure during the merge

  • git merge --abort: It exits from the merge process and returns the branch to the state before the merge began.

    $ git merge --abort 
    
  • git reset: It is used to reset the conflicted files to a known good state.

    $ git reset 
    


ExpectoCode is optimized for learning. Tutorials and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using this site, you agree to have read and accepted our terms of use, cookie and privacy policy.
Copyright 2020-2021 by ExpectoCode. All Rights Reserved.