Resolving a Git Merge Conflict
1. What is it?
A merge conflict occurs when Git cannot automatically decide how to combine changes.
A common situation is when two developers modify the same lines in the same file differently.
For example, the original code is:
var message = "Welcome";
Developer A changes it to:
var message = "Welcome to JNTech";
Developer B changes the same line to:
var message = "Welcome User";
Git cannot know which version is correct, so it stops the merge and asks the developer to manually resolve the conflict.
2. Simple Syntax / Sample
Suppose you are working on:
feature/login
and want the latest main changes.
git switch feature/login
git fetch origin
git merge origin/main
If there is a conflict:
git status
Git shows the conflicted files.
After manually resolving them:
git add LoginService.cs
git commit
Then push:
git push origin feature/login
A typical flow is:
Fetch latest changes
↓
Merge
↓
Conflict detected
↓
Open conflicted files
↓
Understand both changes
↓
Edit and resolve
↓
git add
↓
git commit
↓
Test
↓
git push
3. Detailed Explanation
Suppose Developer A has this change on main:
public string GetMessage()
{
return "Welcome to JNTech";
}
Developer B has this change on feature/login:
public string GetMessage()
{
return "Welcome User";
}
Developer B runs:
git fetch origin
git merge origin/main
Git may report:
CONFLICT (content): Merge conflict in LoginService.cs
Automatic merge failed; fix conflicts and then commit the result.
Step 1: Identify conflicted files
Run:
git status
You may see:
both modified: LoginService.cs
This tells you which files require manual resolution.
Step 2: Open the conflicted file
Git inserts conflict markers:
<<<<<<< HEAD
return "Welcome User";
=======
return "Welcome to JNTech";
>>>>>>> origin/main
The markers mean:
<<<<<<< HEAD
Your current branch's change
=======
Separator
>>>>>>> origin/main
Incoming change
So Git is essentially asking:
Which code should the final file contain?
Step 3: Understand both changes
Do not simply choose your code automatically.
You should determine:
- Why did Developer A make their change?
- Why did Developer B make their change?
- Should we keep Developer A's version?
- Should we keep Developer B's version?
- Should we combine both changes?
In a real development team, if the intention is unclear, discuss the conflict with the other developer.
Step 4: Resolve the conflict manually
Suppose the team decides the correct code should be:
public string GetMessage()
{
return "Welcome to JNTech User";
}
Remove all Git conflict markers:
<<<<<<< HEAD
=======
>>>>>>> origin/main
The file should contain only the final valid code.
Step 5: Mark the conflict as resolved
After fixing the file:
git add LoginService.cs
git add tells Git:
I have resolved the conflict in this file.
Check again:
git status
Step 6: Complete the merge
Run:
git commit
Git creates the merge commit.
You could also specify the message:
git commit -m "Resolve merge conflict with main"
The history may look like:
C ---- main
/ \
A --- B --- M
\ /
D --- feature/login
M represents the merge commit containing the resolved code.
Step 7: Test before pushing
This is an important practical step.
A conflict being syntactically resolved does not necessarily mean the application is functionally correct.
I would normally:
dotnet build
dotnet test
Then, if everything is correct:
git push origin feature/login
4. Resolving Conflicts in Visual Studio
For a .NET development team, you can also resolve conflicts using Visual Studio's Git tools.
Visual Studio typically lets you compare:
Current Change | Incoming Change
You can choose or edit the result:
Take Current
Take Incoming
Take Both
Manually combine changes
The important point is that these options are only tools. You still need to understand the code and decide what the correct final implementation should be.
5. What If the Conflict Happens During Rebase?
Suppose you run:
git pull --rebase origin main
and Git reports a conflict.
Resolve the file and stage it:
git add LoginService.cs
But instead of git commit, normally continue the rebase with:
git rebase --continue
The flow is:
git pull --rebase origin main
↓
Conflict
↓
Resolve file
↓
git add LoginService.cs
↓
git rebase --continue
↓
Test
↓
git push
If you want to cancel the rebase:
git rebase --abort
For a normal merge, you can cancel with:
git merge --abort
6. Merge Conflict vs Rebase Conflict
| Merge conflict | Rebase conflict |
|---|---|
Occurs during git merge |
Occurs during git rebase |
| Resolve files manually | Resolve files manually |
Stage using git add |
Stage using git add |
Complete with git commit |
Continue with git rebase --continue |
Can cancel with git merge --abort |
Can cancel with git rebase --abort |
The actual process of understanding and editing the conflicting code is essentially the same.
7. Key Points
- A merge conflict occurs when Git cannot automatically combine competing changes.
- Changing the same lines differently is a common cause.
- Find conflicts using:
git status
- Git identifies conflicting sections using:
<<<<<<<
=======
>>>>>>>
- Understand both developers' intentions before choosing the final code.
- You can keep one version, the other version, or combine them.
- Remove all conflict markers.
- Stage the resolved file:
git add <file>
- For a merge:
git commit
- For a rebase:
git rebase --continue
- Always build and test after resolving conflicts.
- If the correct behavior is unclear, coordinate with the developer who made the other change rather than guessing.
8. Interview Answer
If two developers changed the same lines and Git cannot merge them automatically, I would first use
git statusto identify the conflicted files. I would open each file, review the current and incoming changes, understand the intention of both developers, and manually create the correct final code. Then I would stage the resolved files usinggit add. If it is a merge, I would complete it withgit commit; if it is a rebase, I would usegit rebase --continue. Finally, I would build and test the application before pushing the resolved changes.