Managing Conflict
If you work with another developer on the same project and edit the same file on different branches simultaneously, both of you may change the same line in the same file. In this case, it is hard to judge which one becomes the master code. This situation is called conflict.
Another case of conflict is the case where one developer deletes a file while another developer continued working on the file.
If you try to merge the branches with a conflict, the Git system won't be able to complete the merge operation automatically. In that case, the Git system creates an alert identifying the location of the conflict through the registered text editor.
The flow chart below illustrates the typical workflow when you run the git merge
command.
- Run the
git merge
command to trigger the merge process. - When there is no conflict, the Git system automatically completes the merge process.
- When there is a conflict, the Git system suspends the automatic merge process. At this point, the merge process is still running manually; the edited files are staged during this process so that the files are ready to be committed.
- If you want to stop the merge operation, run the
git merge --abort
command. When you run the command, the merge operation is aborted and the status of working files and branches will be reverted to the status they had before running thegit merge
command - If you want to resolve the conflict and continue the merge operation, edit the conflicting lines of code to resolve the conflict.
Options to solve a conflict
To resolve the conflict, the Git system suggests four options through the registered text editor like shown in the image below. If you click one of the first three options, the changes are reflected in the text editor. If you click the last "Compare Changes" option, a read-mode text editor launches to show the comparison of the two branches.
- Accept Current Change (Keep the changes on the branch where you are executing the merge command)
- Accept Incoming Change (Keep the changes on the branch being merged)
- Accept Both (Keep both changes)
- Compare Changes
If none of the options 1 - 3 gives what you want, you can also edit the code further to customize the conflict resolution.
- Once the conflict is resolved, you can run the
git commit
command to complete the merge operation
For a better understanding, please go through the following practice section.
Practice
Developer A (Project Owner Role)
Objective:
Solve a conflict
1. Prepare a practice file: create a conflict
At the end of the practice on the previous page, the master branch and Branch_A reached the same status. Check the latest status by running the git log
command.
git log --oneline
You'll see that the HEAD of both the master branch and Branch_A is commit A2.
479f994 (HEAD -> master, Branch_A) A2
6d96103 A1
288068f M5
b7b73d4 M4
e12beda M3
f5ff7aa M2
8bf5c03 M1
To create a conflict, first, revert the master branch to commit M5 by running the git reset --hard
command. Use the commit hash of commit M5 which is generated on your computer. Also, make sure to use the --hard
option. If you don't use the option, the statuses of the Working Tree, Staging Area and HEAD will be mixed up.
git reset --hard 288068f
git log --oneline
You'll see that the HEAD of the master branch is back to Commit M5.
HEAD is now at 1923334 M5
288068f (HEAD -> master) M5
b7b73d4 M4
e12beda M3
f5ff7aa M2
8bf5c03 M1
Next, edit the file like below by adding <h1>M6</h1>
after <!-- Branch_A-->
, which is supposed to be the editing area for Branch_A. After saving the file, run the git commit
command.
<!-- Branch_A-->
<h1>M6</h1>
<!-- /Branch_A-->
git commit -am "M6"
git log --oneline
You can see that the HEAD of the master branch is now at commit M6.
44614a9 (HEAD -> master) M6
288068f M5
b7b73d4 M4
e12beda M3
f5ff7aa M2
8bf5c03 M1
2. Run the merge command: confirm a conflict
Now you can run the merge command expecting there is a conflict.
git merge Branch_A
You'll see a message saying "Automatic merge failed" in the command line.
Auto-merging git_branch_practice.html
CONFLICT (content): Merge conflict in git_branch_practice.html
Automatic merge failed; fix conflicts and then commit the result.
Also, a text editor (VS Code) is opened when you encounter a conflict indicating the location of the conflict as shown below.
<!-- Branch_A-->
<<<<<<< HEAD (Current Change)
<h1>M6</h1>
=======
<h1>A1</h1>
<h1>A2</h1>
>>>>>>> Branch_A (Incoming Change)
<!-- /Branch_A-->
3. Resolve a conflict
VS Code editor shows some options to resolve the conflict. Also, the editor shows the Resolve in Merge Editor button at the bottom. You can select one of the options or press the button.
In this practice, we use the Merge Editor. When you press the Resolve in Merge Editor button, you'll see the comparison between the Incoming change and the Current change with the editing area at the bottom as shown below.
To solve the conflict, we'll move <h1>M6</h1>
to after <h1>M5</h1>
while keeping incoming change (edits on Branch_A). The edited code should look like the one below.
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<h1>M3</h1>
<h1>M4</h1>
<h1>M5</h1>
<h1>M6</h1>
<!-- /Master Branch-->
<!-- Branch_A-->
<h1>A1</h1>
<h1>A2</h1>
<!-- /Branch_A-->
Once the edit is done, press the Complete Merge button.
At this stage, the change is not reflected in any commit. To check the status, run the git status
command.
git status
You can see that the merged code has not been committed yet.
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: git_branch_practice.html
To complete the merge operation, make a new commit.
git commit -am "Merge Branch_A (fixed conflict)"
git log --oneline --graph
Now you can see that Branch_A was successfully merged with the master branch.
* 0bebce9 (HEAD -> master) Merge Branch_A (fixed conflict)
|\
| * 479f994 (Branch_A) A2
| * 6d96103 A1
* | 44614a9 M6
|/
* 288068f M5
* b7b73d4 M4
* e12beda M3
* f5ff7aa M2
* 8bf5c03 M1
The demo code is available in this repository (Demo Code).