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 thegit 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. Runninggit 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