Git Merge vs Rebase and Rebase Conflict Handling
1. When should you use merge vs rebase?
Both merge and rebase integrate changes from different branches, but you choose between them based on how you want to manage the commit history.
When to Use Merge
Use merge when you want to preserve the existing branch history.
For example:
A --- B --- E --- F main
\
C --- D feature/login
From the feature branch:
git switch feature/login
git merge main
Result:
A --- B --- E --- F
\ \
C --- D ---- M
feature/login
M is a merge commit when Git requires one.
Merge is commonly useful when:
- The branch is shared with other developers.
- You want to preserve the actual development history.
- Your team prefers merge-based workflows.
- You do not want to rewrite existing commits.
When to Use Rebase
Use rebase when you want to place your feature commits on top of the latest target branch and maintain a more linear history.
git switch feature/login
git rebase main
Result:
A --- B --- E --- F --- C' --- D'
main feature/login
Rebase is commonly useful when:
- You are working on your own local feature branch.
- You want to update your feature branch with the latest
main. - You want a cleaner, linear history before creating or updating a Pull Request.
- The commits being rebased are not being relied on by other developers.
Merge vs Rebase — Simple Rule
Shared branch/history
↓
MERGE
Private/local feature work
↓
REBASE
This is a useful guideline, but the team's Git policy should take precedence.
Key Points
- Merge preserves existing commit history.
- Rebase rewrites the commits being rebased.
- Merge is generally safer for shared history.
- Rebase is useful for keeping private feature work linear.
- Both approaches can produce the same final file contents; the major difference is how the history is represented.
- Always follow the branching strategy established by your team.
2. Why should you avoid rebasing a shared/public branch?
What is the Problem?
Rebase rewrites commit history.
Suppose you have:
A --- B --- C --- D feature/login
Another developer has already pulled this branch and is working based on commits C and D.
If you rebase the branch, Git may create:
A --- B --- C' --- D'
Although C' and D' may contain similar changes, they are new commits with different commit hashes.
So:
Old commits: C D
New commits: C' D'
Git treats them as different commits.
Simple Example
Developer 1 and Developer 2 initially have:
A --- B --- C --- D
Developer 1 rebases and pushes:
A --- B --- C' --- D'
But Developer 2 still has:
A --- B --- C --- D
Now the developers have different histories.
This can lead to:
- Confusing conflicts
- Duplicate-looking commits
- Difficult synchronization
- Force-push requirements
- Risk of overwriting other developers' work
A rebased branch may also require:
git push --force-with-lease
because the rewritten local history no longer fast-forwards the remote branch.
--force-with-lease is generally safer than --force because it checks that the remote branch has not unexpectedly changed before replacing it.
Safe General Rule
Avoid rebasing commits that other developers have already based their work on.
For example:
Your private feature branch
↓
Rebase can be useful
Shared team branch
↓
Avoid rewriting history
Key Points
- Rebase changes commit hashes.
- Shared branches may already be used by other developers.
- Rewriting them can cause their local history to diverge.
- Updating the rewritten remote branch may require a force push.
- Avoid rewriting branches such as shared
main,develop, or shared feature branches unless your team's workflow explicitly supports it.
3. How do you handle conflicts during a rebase?
A rebase conflict occurs when Git cannot automatically apply one of your commits on top of the new base.
Simple Example
Suppose main changed:
var message = "Welcome";
Your feature branch changed the same line:
var message = "Welcome User";
When you execute:
git rebase main
Git may not know which change should be retained.
It stops the rebase and reports a conflict.
Step 1: Start Rebase
git switch feature/login
git rebase main
You may see:
CONFLICT (content): Merge conflict in Login.cs
Step 2: Check the Conflict
git status
Git shows the conflicting files.
For example:
both modified: Login.cs
Step 3: Open the Conflicting File
Git may show conflict markers:
<<<<<<< HEAD
var message = "Welcome";
=======
var message = "Welcome User";
>>>>>>> feature commit
You decide what the final code should be.
For example:
var message = "Welcome User";
Remove the conflict markers:
<<<<<<<
=======
>>>>>>>
Step 4: Stage the Resolved File
After resolving the conflict:
git add Login.cs
Or stage all resolved files:
git add .
Step 5: Continue the Rebase
git rebase --continue
Git continues replaying the remaining commits.
If another conflict occurs, repeat:
Resolve conflict
↓
git add .
↓
git rebase --continue
Abort the Rebase
If you decide not to continue:
git rebase --abort
This cancels the rebase and restores the branch to its state before the rebase started.
Complete Flow
git switch feature/login
git rebase main
# Conflict occurs
git status
# Edit and resolve conflicting files
git add .
git rebase --continue
If more conflicts occur:
# Resolve them
git add .
git rebase --continue
Or cancel everything:
git rebase --abort
Rebase Conflict Flow
git rebase main
↓
Conflict?
↓
Yes
↓
git status
↓
Open conflicting file
↓
Choose/fix correct code
↓
git add <file>
↓
git rebase --continue
↓
More conflicts?
↓ ↓
Yes No
↓ ↓
Repeat Complete
Key Points
- Rebase processes your commits one at a time, so conflicts can occur at different points during the rebase.
- Use
git statusto identify conflicting files. - Manually resolve the conflicts.
- Stage resolved files using
git add. - Continue using:
git rebase --continue
- Cancel using:
git rebase --abort
- After rebasing a branch that was already pushed, updating the remote may require a force push. When appropriate under your team's policy, prefer:
git push --force-with-lease
over:
git push --force
because --force-with-lease provides protection against accidentally overwriting unexpected remote changes.