Git Merge and Merge Conflict Management
1. What is Git merge, and how do you merge one branch into another?
What is Git Merge?
Git merge is used to combine changes from one branch into another branch.
Suppose you have:
main
feature/login
You developed the login functionality in feature/login and now want to bring those changes into main.
Simple Syntax
First switch to the destination branch:
git switch main
Then merge the source branch:
git merge feature/login
The important rule is:
Switch to the branch that should receive the changes, then merge the other branch into it.
So:
git switch main
git merge feature/login
means:
feature/login
|
| merge changes into
v
main
Simple Example
Before:
A --- B --- C main
\
D --- E feature/login
Run:
git switch main
git merge feature/login
After merging:
A --- B --- C --- D --- E
main
This particular example can be a fast-forward merge because main has not changed since the feature branch was created.
Typical Workflow
# Switch to main
git switch main
# Get latest main
git pull
# Merge feature branch
git merge feature/login
# Push updated main
git push
In many professional workflows, developers do not merge directly into main; instead, the merge happens through a Pull Request (PR) after review and CI checks.
Key Points
git mergecombines branch histories.- Always know which branch is the destination.
- To merge
feature/loginintomain:
git switch main
git merge feature/login
- Merge generally preserves the existing commit history.
- A merge can be fast-forward or involve a merge commit, depending on branch history.
2. What is the difference between fast-forward and three-way merge?
Both are ways Git can perform a merge.
Fast-Forward Merge
A fast-forward merge happens when the destination branch has no new commits since the other branch was created.
Suppose:
A --- B main
\
C --- D feature/login
main is still at B.
Run:
git switch main
git merge feature/login
Git can simply move the main pointer from B to D.
After:
A --- B --- C --- D
↑
main, feature/login
No merge commit is required.
Why is it called fast-forward?
Because Git does not need to combine two diverged histories.
It simply moves:
main: B → D
Three-Way Merge
A three-way merge is needed when both branches have changed after their common ancestor.
Before:
C --- D main
/
A --- B
\
E --- F feature/login
Here:
B= common ancestorD= latestmainF= latestfeature/login
Run:
git switch main
git merge feature/login
Git considers three snapshots:
1. Common ancestor → B
2. Current branch → D
3. Branch to merge → F
Git combines them and normally creates a merge commit:
C --- D
/ \
A --- B M main
\ /
E --- F
M is the merge commit.
Fast-Forward vs Three-Way Merge
| Fast-Forward | Three-Way |
|---|---|
| Branches have not diverged | Both branches have changed |
| Simply moves branch pointer | Combines two histories |
| No merge commit required | Usually creates a merge commit |
| Simple linear history | Preserves branch structure |
| Uses the existing commit path | Uses common ancestor + two branch tips |
Key Points
- Fast-forward happens when the destination branch is directly behind the source branch.
- Three-way merge happens when branches have diverged.
- Three-way merge uses three snapshots: common ancestor and the tips of both branches.
- A three-way merge normally creates a merge commit.
3. What is a merge conflict, why does it occur, and how do you resolve it?
What is a Merge Conflict?
A merge conflict occurs when Git cannot automatically determine how changes from two branches should be combined.
For example, main contains:
string message = "Welcome";
But feature/login changed the same line to:
string message = "Welcome User";
If the same area was changed incompatibly on both branches, Git may require a developer to decide what the final code should be.
Why Do Merge Conflicts Occur?
Common reasons include:
- Two developers modify the same line.
- One branch modifies a file while another deletes it.
- Both branches make incompatible changes to the same section.
- Long-running branches accumulate many differences.
Simple Example
Run:
git switch main
git merge feature/login
Git may report:
CONFLICT (content): Merge conflict in Login.cs
Automatic merge failed; fix conflicts and then commit the result.
Check the conflict:
git status
Git may show:
both modified: Login.cs
Open Login.cs.
Git adds conflict markers similar to:
<<<<<<< HEAD
string message = "Welcome";
=======
string message = "Welcome User";
>>>>>>> feature/login
Here:
<<<<<<< HEAD
shows the current branch's version.
=======
separates the two versions.
>>>>>>> feature/login
marks the incoming branch's version.
Resolve the Conflict
You manually decide the correct final code.
For example:
string message = "Welcome User";
Remove all conflict markers:
<<<<<<<
=======
>>>>>>>
Then stage the resolved file:
git add Login.cs
Or:
git add .
Key Points
- A conflict means Git needs human input.
- It commonly occurs when overlapping code is changed differently.
- Use:
git status
to identify conflicted files.
- Edit the files and decide the correct final content.
- Remove Git's conflict markers.
- Stage the resolved files using
git add.
4. What should you do after resolving a merge conflict?
After manually resolving all conflicts, you need to tell Git that the conflicts have been resolved.
Step 1: Check Status
git status
Step 2: Resolve the Files
Edit the conflicting files and make sure the final code is correct.
Step 3: Stage Resolved Files
git add .
Or stage individual files:
git add Login.cs
Step 4: Complete the Merge
Usually:
git commit
Git will provide a default merge commit message, which you can accept or modify.
For example:
git commit -m "Merge feature/login into main"
Step 5: Test the Application
This is very important.
A conflict may be textually resolved but still produce incorrect application behavior.
Run:
Build
↓
Unit tests
↓
Integration tests
↓
Application testing
For example, in a .NET project:
dotnet build
dotnet test
Step 6: Push
After verifying the merge:
git push
Complete Flow
git switch main
git merge feature/login
# Conflict occurs
git status
# Manually fix conflicting files
git add .
git commit
# Verify the application
dotnet build
dotnet test
git push
Abort the Merge
If you want to cancel an in-progress merge:
git merge --abort
This attempts to return the working tree to its pre-merge state.
Key Points
After resolving conflicts:
Resolve
↓
git add
↓
git commit
↓
Build/Test
↓
git push
Do not treat git add alone as completing the merge. For a normal conflicted merge, the merge must still be committed.
5. How can a team reduce merge conflicts?
Merge conflicts cannot always be eliminated, but good development practices can significantly reduce them.
Keep Branches Short-Lived
Avoid working on the same feature branch for weeks without synchronizing it.
Instead of:
main
feature
↓
Work for 3 weeks
↓
Merge
prefer smaller, frequently integrated changes:
Small change
↓
Commit
↓
PR
↓
Merge
The longer branches diverge, the greater the chance of conflicts.
Frequently Update Feature Branches
Bring recent changes from the target branch into your feature work regularly.
For example:
git switch main
git pull
git switch feature/login
git merge main
Or, if your team's workflow uses rebase:
git switch feature/login
git rebase main
Divide Work Clearly
Avoid having multiple developers unnecessarily modify the same code.
For example:
Developer A → Login functionality
Developer B → Payment functionality
Developer C → Reporting functionality
This does not mean developers can never touch the same files, but clear ownership and coordination reduce overlapping edits.
Make Small Commits and Pull Requests
Prefer focused changes:
Small feature
Small PR
Quick review
Quick merge
rather than:
Huge feature
Hundreds of changed files
Large PR
Delayed merge
Smaller changes are easier to review, integrate, and troubleshoot.
Communicate Before Major Refactoring
Suppose one developer is restructuring:
Services/
Controllers/
Repositories/
while several other developers are actively modifying those files.
That can create many conflicts.
Teams should coordinate major refactoring before making broad structural changes.
Avoid Unnecessary Formatting Changes
Changing formatting across an entire file can create conflicts even when the functional change is small.
For example, changing one method should ideally not unnecessarily reformat hundreds of unrelated lines.
Key Points
A team can reduce conflicts by:
- Keeping feature branches short-lived.
- Regularly synchronizing with the target branch.
- Dividing work clearly among developers.
- Creating small, focused commits and Pull Requests.
- Merging completed work frequently.
- Coordinating large refactoring changes.
- Avoiding unnecessary edits or formatting changes in unrelated code.
Interview Answer
A merge conflict occurs when Git cannot automatically combine changes from different branches, commonly because the same code was changed incompatibly. I resolve the conflicting files manually, stage them with
git add, complete the merge withgit commit, test the application, and then push the changes. Teams can reduce conflicts by using short-lived branches, small PRs, frequent synchronization, and good coordination among developers.