Merge and Rebase
Core Strategy
Rebase: Use when bringing changes from main into your feature branch
Merge: Use when integrating your feature branch into main (via MR/PR)
| Aspect | Rebase | Merge |
|---|---|---|
| History | Linear, clean | Preserves branching context |
| Command | git rebase origin/main | git merge feature-branch |
| Conflicts | Resolve per commit | Resolve once |
| Force Push | Required after rebase | Not needed |
| Team Impact | Changes commit hashes | Safe for shared branches |
| Best For | Keeping feature current | Final integration |
Example Scenario
Initial State
You create a feature branch from commit F, then make several commits while main continues to evolve:
main A---B---C---D---E---F---L---M
\
feature G---H---I---J---K
- F: Common ancestor where feature branched off
- G–K: Your feature branch commits
- L–M: New commits added to main after you branched
The Problem
Your feature branch is now behind main, which can cause:
- Merge conflicts when creating your MR
- A messy history with unnecessary merge commits
- Difficulty understanding what your feature actually changed
Pre-Merge Request Workflow
Step 1: Fetch Latest Changes
git fetch origin
Step 2: Analyze What’s Changed
Before rebasing, understand what you’re working with:
# See what commits are on main that you don't have
git log --oneline HEAD..origin/main
# See the actual code differences
git diff origin/main
This helps you anticipate potential conflicts and understand the scope of changes.
Step 3: Rebase Your Feature Branch
git rebase origin/main
This replays your commits (G–K) on top of the latest main (M), creating a clean linear history:
main A---B---C---D---E---F---L---M
\
feature G'--H'--I'--J'--K'
Step 4: Update Remote Branch
git push --force-with-lease
Why --force-with-lease? It’s safer than --force because it fails if someone else has pushed to your branch, preventing you from accidentally overwriting their work.
Step 5: Create Merge Request
Now your feature branch is up-to-date and ready for a clean merge request through your Git platform’s UI.
Handling Rebase Conflicts
When Conflicts Occur
During rebase, you might see:
CONFLICT (content): Merge conflict in README.md
error: could not apply abc1234... Update project description
Resolution Process
1. Identify Conflict Markers
Open the conflicted file and look for:
<<<<<<< HEAD
# My Project
Welcome to my project repository.
=======
# My Project
Welcome to my awesome project repository with new features.
>>>>>>> abc1234 Update README with new description
2. Resolve the Conflict
Choose the version you want or combine them:
# My Project
Welcome to my awesome project repository with new features.
Remove all conflict markers (<<<<<<<, =======, >>>>>>>)
3. Stage and Continue
# Stage the resolved file
git add README.md
# Continue the rebase process
git rebase --continue
4. Repeat if Necessary
If you have multiple commits being rebased, you might need to resolve conflicts for each one. The process repeats until all commits are successfully applied.
Success Indicators
When rebase completes successfully:
Successfully rebased and updated refs/heads/feature-branch-name.
Emergency Exit
If things go wrong and you want to start over:
git rebase --abort
This returns your branch to exactly where it was before you started the rebase.
Best Practices
Before Starting
- Always work on a feature branch, never directly on main
- Keep commits focused and atomic (one logical change per commit)
- Write clear, descriptive commit messages
During Development
- Rebase frequently to stay current with main
- Test your code after rebasing to ensure nothing broke
- Use
git statusandgit log --onelineto understand your current state
Before Merge Request
- Ensure all tests pass after rebasing
- Review your changes with
git diff origin/main - Consider squashing related commits to clean up history
Communication
- Notify before force-pushing shared branches to avoid conflicts
- Add context in MR descriptions about significant conflicts resolved
- Tag relevant reviewers who need to understand the integration
- Thread resolution - only the original commenter should resolve discussions unless explicitly delegated
- Respond to each comment individually with brief acknowledgments:
- “Addressed in latest commit”
- “Fixed in [commit hash]”
- “Could you clarify X?”
- “Updated as suggested”
This workflow ensures your feature branches integrate cleanly with main while preserving both development history and project timeline clarity.