Git examples of rebasing with conflicts: 3 practical examples for real teams
Modern teams are rebasing more than ever. Trunk-based development, protected main branches, and auto-merge bots all push developers toward git rebase instead of long-running merge commits. That’s why examples of rebasing with conflicts: 3 practical examples matter more now than they did five years ago.
In 2024–2025, you’ll see conflicts pop up most often when:
- Feature branches live longer than they should.
- Multiple engineers touch the same hot files (think
routes,package.json, or a centralconfigfile). - Automated tools (formatters, AI code assistants, linters) rewrite code you just edited.
Let’s walk through the best examples you’re likely to hit in day-to-day work, then generalize patterns you can reuse.
Example of rebasing with conflicts #1: Two developers editing the same function
This is the classic scenario people mean when they talk about examples of rebasing with conflicts: 3 practical examples.
Setup
mainhas a functioncalculateTotal()incart.js.- Alice creates
feature/discountsand adds discount logic. - Bob creates
feature/tax-refactorand changes how taxes are calculated. - Bob’s branch gets merged to
mainquickly. - A day later, Alice rebases her branch on top of the new
main.
What happens
Alice runs:
git checkout feature/discounts
git fetch origin
git rebase origin/main
Git stops with a conflict on cart.js:
CONFLICT (content): Merge conflict in cart.js
The file now has conflict markers:
function calculateTotal(cart) {
<<<<<<< HEAD
// Alice's discount logic
const subtotal = cart.items.reduce((sum, item) => sum + item.price, 0);
const discount = getDiscount(cart.user, subtotal);
const tax = calculateTax(subtotal - discount);
return subtotal - discount + tax;
=======
// Bob's tax refactor
const subtotal = cart.items.reduce((sum, item) => sum + item.price, 0);
const tax = calculateTax(subtotal, cart.region);
return subtotal + tax;
>>>>>>> origin/main
}
How to think about the resolution
Instead of mindlessly picking “ours” or “theirs,” ask:
- What is the behavior on
mainnow? (Bob’s tax refactor, including region.) - What behavior do I introduce on my branch? (Discounts.)
- How do these behaviors combine?
A reasonable resolution might be:
function calculateTotal(cart) {
const subtotal = cart.items.reduce((sum, item) => sum + item.price, 0);
const discount = getDiscount(cart.user, subtotal);
const taxableAmount = subtotal - discount;
const tax = calculateTax(taxableAmount, cart.region);
return taxableAmount + tax;
}
Then you mark the conflict as resolved:
git add cart.js
git rebase --continue
Key takeaway
In this first of our real examples of rebasing with conflicts: 3 practical examples, the right answer is rarely “keep my version” or “keep theirs.” It’s almost always “merge the ideas.”
Example of rebasing with conflicts #2: Deleted file vs. modified file
Another one of the best examples of rebasing with conflicts appears when one branch deletes a file that another branch modifies.
Setup
maincontainslegacy-report.js.- The
cleanup/legacy-reportbranch deleteslegacy-report.jsand is merged tomain. - Your
feature/new-reporting-uibranch, started earlier, still editslegacy-report.jsto add some quick fixes.
When you rebase your feature branch on top of main:
git checkout feature/new-reporting-ui
git fetch origin
git rebase origin/main
Git complains:
CONFLICT (modify/delete): legacy-report.js deleted in origin/main and modified in HEAD.
How to interpret this
Git is saying: “On the new base (origin/main), this file is gone. On your branch, you changed it. I don’t know what you meant.”
Your options:
- Keep the deletion: your branch should also drop the file.
- Restore the file: your changes mean the file should live on.
If the team decided to kill the legacy report, you probably want to keep the deletion:
## Tell Git we accept the deletion
git rm legacy-report.js
git rebase --continue
If you actually need the file back (maybe the new UI still depends on it), you can resurrect it from your branch version:
## Check out your version of the file from before the rebase conflict
git checkout HEAD -- legacy-report.js
git add legacy-report.js
git rebase --continue
Key takeaway
This second scenario in our examples of rebasing with conflicts: 3 practical examples shows that conflicts can be about intent, not just text. You’re deciding whether a deletion was intentional and final, or premature.
Example of rebasing with conflicts #3: Auto-formatters and AI assistants rewriting code
The third of our examples of rebasing with conflicts: 3 practical examples is increasingly common in 2024–2025: automatic tools rewriting code.
Setup
- The team just adopted
prettieror a strict ESLint rule set. mainhas been reformatted by a big “Apply formatter to repo” commit.- Your feature branch was created before that refactor and has real logic changes in the same files.
- Maybe you’re also using an AI coding assistant that occasionally rewrites functions.
When you rebase:
git checkout feature/new-search
git fetch origin
git rebase origin/main
You see conflicts in multiple files that look like they’re just formatting, but some lines hide actual logic changes.
How to avoid getting burned
This is where people accidentally lose work. A few patterns help:
Use
git diff --ignore-all-spaceto see if the conflict is purely formatting:git diff --ignore-all-space HEAD origin/main -- path/to/file.jsIf the big formatting change is already merged, consider rebasing in two steps:
- First rebase onto the commit before the formatter.
- Then rebase onto the formatter commit and resolve mostly mechanical conflicts.
Use a three-way diff tool (
git mergetool) to visually compareours,theirs, andbase.
Example resolution
Suppose main’s version is:
function searchUsers(query) {
return db.users
.filter((user) => user.name.toLowerCase().includes(query.toLowerCase()))
.sort((a, b) => a.name.localeCompare(b.name));
}
Your branch adds a new filter but in a slightly different style. The conflict markers may look noisy, but your goal is to keep:
- The formatting from
main. - The logic from your branch.
You might end up with:
function searchUsers(query) {
const normalizedQuery = query.trim().toLowerCase();
return db.users
.filter((user) => !user.disabled)
.filter((user) => user.name.toLowerCase().includes(normalizedQuery))
.sort((a, b) => a.name.localeCompare(b.name));
}
Key takeaway
With modern tooling, one of the most realistic real examples of rebasing with conflicts: 3 practical examples is “logic change vs. mass reformat.” Treat those differently from normal conflicts; don’t just take the formatted version and hope.
More real examples: config files, dependency bumps, and binary conflicts
The headline promised examples of rebasing with conflicts: 3 practical examples, but in practice you’ll see the same patterns in several other spots. A few more concrete examples include:
Shared config files (package.json, pom.xml, settings.gradle)
Two engineers bump different dependencies in package.json on separate branches. One branch is merged; the other rebases and hits:
CONFLICT (content): Merge conflict in package.json
Instead of picking one side, you usually want a merged dependencies section that includes both new versions. This is where a JSON-aware merge tool or npm dedupe can help after you resolve the conflict.
API schema changes
Your backend team changes an API response shape in openapi.yaml on main. Your feature branch modifies the same endpoints’ documentation.
When you rebase, Git can’t reconcile the two YAML edits. The right move is to:
- Accept the new schema from
main. - Reapply your documentation or client changes to match that schema.
This mirrors the first of our examples of rebasing with conflicts: 3 practical examples, but in a schema file instead of source code.
Binary files (design assets, migrations, or data dumps)
If two branches edit the same binary file (a .psd, .png, or a large data dump), Git will give you a conflict it can’t auto-merge.
You’ll see something like:
CONFLICT (content): Merge conflict in assets/logo.png
Here, your choice is binary (literally): keep one version or the other, or store both under different names. There’s no line-by-line merge.
Patterns across all examples of rebasing with conflicts
Across all these examples of rebasing with conflicts: 3 practical examples and the extra scenarios, a few patterns repeat:
1. Conflicts are about intent, not just text
Git shows you text differences, but your job is to decode intent:
- Is this a refactor that should be combined with new logic?
- Is this a deletion that should stay deleted, or should the file come back?
- Is this pure formatting, or did behavior change?
2. Short-lived branches reduce pain
Teams that keep branches short-lived see fewer and simpler conflicts. That lines up with research on software delivery performance, like the findings summarized in the U.S. Digital Service playbook about small, frequent changes.
3. Rebasing vs. merging is a tradeoff
Rebasing keeps history linear, which many teams prefer. But if your branch has already been pushed and used by others, rebasing can be risky because it rewrites history. For guidance on version control best practices in collaborative environments, you can look at materials from universities that teach software engineering, such as MIT’s 6.031 Software Construction course notes.
4. Tooling can help, but you still need judgment
Modern tools (VS Code’s merge editor, GitHub’s conflict UI, AI assistants) can surface options, but they can’t read your product requirements. You still need to:
- Run tests.
- Re-check critical business logic.
- Confirm behavior with product or QA when in doubt.
Practical workflow tips when you hit a rebase conflict
When any of these examples of rebasing with conflicts: 3 practical examples (or their cousins) hit you mid-rebase, a disciplined workflow keeps you from making things worse.
Pause and inspect
- Use
git statusto see all conflicted files. - For each file, run
git diffto understand what changed.
Use three-way diff tools
Configure a merge tool once and reuse it:
git config --global merge.tool vimdiff # or meld, kdiff3, etc.
git mergetool
This helps you see BASE, LOCAL, and REMOTE at the same time.
Don’t be afraid to abort
If you realize mid-way that the rebase is too messy:
git rebase --abort
You’re back where you started. At that point, you can:
- Try a regular merge instead of a rebase.
- Split your branch into smaller commits.
- Coordinate with teammates about big refactors.
For general guidance on debugging complex software issues and when to back out of risky changes, the Carnegie Mellon Software Engineering Institute has research and guidance that’s worth browsing, especially if you work on safety-critical systems.
FAQ: common questions about rebasing with conflicts
What are some real-world examples of rebasing with conflicts in Git?
Real-world examples include two developers editing the same function, one branch deleting a file while another modifies it, large formatter or refactor commits colliding with feature work, conflicting dependency updates in package.json, and incompatible changes to shared API schemas or configuration files.
How do I decide whether to keep my changes or the ones from main during a rebase?
Think in terms of behavior, not ownership. Ask what the system should do now, given the latest decisions on main. Often, you’ll combine both sides: keep new behavior from your branch while preserving refactors, bug fixes, or security patches from main.
Is there a simple example of a rebase conflict that beginners can practice with?
Yes. A simple example of a rebase conflict is: create a repo, add a function, branch off, edit the function differently on both main and your branch, then rebase the branch onto main. You’ll see a conflict in that file and can practice editing between the conflict markers, then running git add and git rebase --continue.
When should I prefer merge over rebase to avoid painful conflicts?
If the branch is already shared with others, or if the history is long and tangled with many refactors, a regular merge may be safer. Rebase shines for local cleanups and short-lived branches; merges are often better for long-running feature branches already visible to the team.
Can rebasing with conflicts lose data?
Git doesn’t throw away data immediately, but a careless conflict resolution can effectively lose logic by overwriting it. The good news: you can often recover with git reflog if you realize it soon enough. Still, the best defense is careful review, running tests, and not rushing through conflict markers.
Related Topics
Real‑world examples of branch conflict examples in Git
Real-world examples of merge conflict handling examples in GitHub
Git examples of rebasing with conflicts: 3 practical examples for real teams
Real-world examples of examples of merge conflict in Git
When Your Git History Turns Into a Battlefield
Explore More Version Control Conflicts
Discover more examples and insights in this category.
View All Version Control Conflicts