Git is a popular, open-source, distributed version control system that allows multiple software developers and teams to concurrently build applications and websites. Since it allows many people to work on the same code repository at the same time, it is possible that this results in merge conflicts, where different developers have updated the same piece of code or file. In fact, this is a common occurrence in git repositories. In this article, we will learn how to resolve merge conflicts in git. They can be applied to all platforms – mac, windows or linux.
What is Git Merge Conflict
Merge conflicts occur if there are two commits with changes to the same lines of a file, or the same file. For example, if two developers working on different branches of same git repository, commit changes to the same lines of a file, then it may result in a merge conflict. Similarly, if one developer deletes a file on one branch, while the other developer commits changes to this file without deleting it, then also it will cause merge conflict. Git will automatically merge two commits only if the commits are pertaining to different lines of same file, or they are related to different files.
Please note, these merge conflicts can happen whether these two commits belong to same or different branches. They can occur if you try to merge to local branches. They can even occur if you push a local commit to a remote branch, or pull a remote branch to local repository. The key point to remember is that a merge conflict happens between two commits and not branches. So it can occur wherever there is a requirement to combine two commits.
Types of Git Merge Conflicts
There are several places where git merge conflict can occur. Let us look at the most common use cases.
1. Pending Changes
If there are pending changes that have not been committed in any of the commits that are being merged, it will result in a conflict, unless you commit those changes using ‘git commit’ command or stash them using ‘git stash’ command.
2. Conflicting File Contents
If the same file has been modified in two separate commits, git will try to merge them as much as possible. But if the same lines of the file have been modified in both commits, then it will give a merge conflict. It will do this for all files where the same lines have been modified in two different commits. Nevertheless, git will merge all other files successfully.
3. Conflicting Files
In this case, one developer may edit a file and commit the changes in his/her branch while another developer completely delete the file and commits the changes in his/her branch. At the time of merging, git will not be able to determine whether to keep or delete the file and result in merge conflict.
Example of Merge Conflict
Let us look at a simple case of merge conflict to help you understand what happens exactly.
Let us initialize git repository called demo.
$ git init demo
$ cd demo
Let us create a new branch b1 for this repository and checkout this new branch.
$ git checkout -b b1
Let us create a new file test.txt in this branch.
$ vi test.txt
Add some content to it (e.g. hello world), save & close the file. Check the status of this file.
$ git status
You will see the following line in red indicating that the a new file has been added to repository but it is not staged yet.
modified: test.txt
Run the following command to stage it (start tracking changes to it).
$ git add .
Run the following command to commit the changes.
$ git commit -am "test commit"
Create a new branch b2 and switch to it.
$ git checkout -b b2
Create a new file with same file name test.txt and add the text ‘good morning’ to it. Save and close the file.
$ vi test.txt
Check the status of changes.
$ git status
You will again see the following line in red indicating that the file is untracked.
modified: test.txt
Add the file and commit the changes.
$ git add .
$ git commit -am "test changes 2"
Now switch back to b1 and make some more changes to test.txt file, say, add ‘good bye’ to it. Save and close the file. Commit those changes.
$ git checkout b1
$ vi test.txt
$ git add .
$ git commit -am "test commit"
We are still working in branch b1. Now if you try to merge branch b2 to branch b1, you will get merge conflict.
$ git merge b2
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
How to Resolve Merge Conflicts in Git
There are two ways to resolve merge conflicts. Let us look at them one by one.
Resolving File Content Conflicts
If you modify the same lines of same file in different git branches and commit those changes, then you will get a merge conflict when you try to merge these two branches. You can fix this problem by creating a new commit before you merge these branches.
Go to your repository and run git status to see the conflicting file. The part in bold clearly says there is a merge conflict that you need to fix.
$ cd demo
$ git status
On branch b1
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: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Open the conflicting file in text editor.
$ vi test.txt
You will see the following lines.
<<<<<<< HEAD
hello world
good bye
=======
good morning
>>>>>>> b2
You will see conflict marker <<<<<< followed by HEAD meaning the present branch you are in, that is, b1. This is followed by the conflicting changes made in that branch b1. Then you will see the separator ======= that separates changes in b1 with those in b2. This is followed by conflicting changes in b2 followed by merge conflict marker >>>>>>> followed by branch name b2. Non conflicting changes are left untouched.
You need to decide whether to keep the version of b1 or b2 or a combination of the two or completely different content altogether at that place. Remove conflict markers <<<<<<<, =======, >>>>>>>. Save and close the file. We have chosen to combine changes from both b1 and b2.
hello world
good bye
good morning
Add the file once again to your staging area.
$ git add .
Commit changes.
$ git commit -m 'resolved merge conflict'
This will produce the merged commit.
Resolving File Merge Conflicts
This kind of conflict occurs if one developer deletes a file in one branch, commits changes and another developers edits the file in another branch, and commits changes. In this case, you will have to decide whether to keep or delete the file. Let us say one developer deletes test.txt file in b1 and another developer edits test.txt in b2 and commits those changes.
To keep the file, use the following command.
$ git add test.txt
To remove the file, use git rm command.
$ git rm text.txt
Lastly, commit the changes to resolve merge conflict and created merged commit.
$ git -m 'resolved merge conflict'
Git Commands to Resolve Merge Conflicts
You can use the following commands to quickly identify the conflicting areas of code and fix them easily.
1. git log –merge
git log command show commit logs. If you provide –merge option to it, then it will list only those commits where merge conflict has occured.
2. git diff
git diff command helps you to identify the differences between two files or repositories.
3. git checkout
git checkout command is used to switch branches, or undo file changes
4. git stash
git stash is used to stash all uncommitted changes
5. git merge –abort
This command helps you completely abort git merge and restore the state before merging started.
6. git reset
git reset command will help you undo changes in conflicting files and restore them to their original state.
FAQs
Here are some commonly asked questions about git merge.
1. How to avoid merge conflicts?
Make sure your developers work in isolated branches and there is proper communication when they are working on common files. Also, while working with local copies of remote repositories, use ‘git pull’ command before you push any changes to remote repository.
2. Do changes made to same file always cause merge conflict?
No. If different developers make changes to different parts of the same file, then there will not be any conflict. However, if they edit the same parts of the file, then there may be conflict. If the commit sequence is such that git is able to resolve the changes, then also there will not be any conflict.
3. Are there any merge tools to directly resolve merge conflicts?
There are certain merge tools such as Meld or KDiff3 or ‘git mergetool’ that provide a GUI representation of merge conflicts. But in all cases, you need to manually resolve the merge conflict. If it was automatically possible to resolve the conflict, ‘git merge’ would have done it already. It shows the merge conflict error because it is unable to do so.
Conclusion
In this article, we have learnt what is git merge conflict, why it occurs, and different types of conflicts. We have also learnt different ways to resolve merge conflicts in git. We have also seen a simple example to demonstrate merge conflict and steps to resolve them. Unfortunately, all merge conflicts have to be manually resolved. There is no way around it. All the git commands only help you quickly identify merge conflicts and verify if your steps have resolved them. If you encounter merge conflict in your software development project, you can use these steps to resolve them as per your requirement.
Also read:
How to Execute System Command in Python
How to JavaScript Closures Work
How to See Foreign Keys in MySQL
Sreeram Sreenivasan is the Founder of Ubiq. He has helped many Fortune 500 companies in the areas of BI & software development.