Chapter 10-4 — Long Running PR Conflicts | DevInHyderabad☕ ☕ 15 min read

Long Running PR Conflicts

PR lamba chale toh conflicts exponential badhte hain. Jaldi merge karo ya jaldi conflict aayega.

01The Problem: Stale PRs Create Conflict Nightmares

The longer a PR stays open, the more the target branch (main) diverges from your PR branch. Other developers merge changes that may conflict with yours. The longer you wait, the more conflicts accumulate.

Conflict complexity grows EXPONENTIALLY, not linearly. A 1-week-old PR might have 3 conflicts. A 2-week-old PR might have 15. The rate accelerates because more code changes overlap as time passes.

"I will merge it later" is the most dangerous phrase in team development. Later = more conflicts = more risk = more time wasted.

Long-running PRs are a code smell: they indicate the PR is too large, the review process is too slow, or the branching strategy is wrong.

# The lifecycle of a stale PR

# Day 1: PR created, clean, no conflicts
git checkout -b feature/login
# Make changes, push PR → ✅ Clean, ready for review

# Day 5: Main has moved forward
git fetch origin
git log --oneline main..origin/main
# 12 new commits on main!
# Some touch the same files you modified

# Day 10: Conflicts begin
git merge origin/main
# CONFLICT in 3 files!
# Resolve, push → PR is updated

# Day 15: More conflicts, reviewer requests changes
# Resolve conflicts AGAIN + make code changes
# The PR is now a MESS of merge commits and conflict resolutions

# Day 20: Nobody wants to review this monster anymore
# The PR is 500 lines changed with 8 merge commits
# Review is surface-level at best
02Strategy 1: Rebase Daily to Prevent Conflicts

The #1 prevention strategy: keep your branch updated with main by rebasing daily.

git fetch origin && git rebase origin/main — replay your commits on top of the latest main.

Daily rebasing means you resolve conflicts in SMALL pieces, before they compound. One day of divergence = 0-1 small conflicts. One week = 3-5 medium conflicts. One month = 10+ complex conflicts.

After rebase: git push --force-with-lease origin feature — force push is required because history changed. The --force-with-lease flag is safer than --force because it checks that nobody else pushed to the branch.

If your team prefers merge commits: git fetch origin && git merge origin/main — simpler but creates merge commits in your PR history.

Make this a habit: before starting work each day, rebase onto latest main.

# The daily rebase habit (BEST prevention)

# Every morning before starting work:
git checkout feature/login
git fetch origin

# Check if main has new commits
git log --oneline origin/main ^feature/login | head -5

# Rebase onto latest main
git rebase origin/main

# If conflicts occur (small, manageable):
# Resolve conflict in file
git add <resolved-file>
git rebase --continue

# Force push updated branch
git push --force-with-lease origin feature/login

# Why daily? Because:
# - 1 day of divergence = 0-1 small conflicts (2 min to fix)
# - 1 week of divergence = 3-5 medium conflicts (30 min to fix)
# - 1 month of divergence = 10+ complex conflicts (hours to fix)

# Alternative: merge main into your branch
git merge origin/main
# Easier than rebase but creates merge commits
# Reviewer sees merge noise in the PR
03Strategy 2: Break Large PRs into Small Ones

Small PRs = fewer conflicts = faster review = faster merge = less divergence. This is a virtuous cycle.

Rule of thumb: PRs should be under 400 lines changed. Beyond that, split it up.

How to split a large feature into small PRs:

  • PR 1: Data model + database migration
  • PR 2: API endpoint
  • PR 3: Frontend UI
  • PR 4: Integration tests

Each PR is independently reviewable and mergeable. If one conflicts, the others can still go in.

Feature flags: merge incomplete features behind a flag, then enable later. This eliminates the need for long-lived feature branches entirely.

# BEFORE: One giant PR
git checkout -b feature/entire-ecommerce
# 2000 lines changed, 20 files, 3 weeks of work
# Nobody wants to review this
# Conflicts with EVERYTHING

# AFTER: Split into small, focused PRs

# PR 1: Database schema (50 lines, 2 files)
git checkout -b feature/ecommerce-schema
# Add product table, order table
# Quick review, merge in 1 day → ✅ No conflicts

# PR 2: Product API (120 lines, 3 files)
git checkout -b feature/ecommerce-api
# CRUD endpoints for products
# Quick review, merge in 1 day → ✅ No conflicts

# PR 3: Cart logic (200 lines, 4 files)
git checkout -b feature/ecommerce-cart
# Add to cart, remove from cart
# Review in 2 days → ✅ Minimal conflicts

# PR 4: Frontend UI (300 lines, 5 files)
git checkout -b feature/ecommerce-ui
# Product page, cart page
# Review in 2 days → ✅ Minimal conflicts

# Each PR is small, focused, and quick to merge
# Total time: same, but NO conflict nightmares
04Strategy 3: Fresh Branch When Conflicts Overwhelm

If your PR has massive conflicts that are too complex to resolve cleanly, start fresh.

Create a new branch from latest main, then cherry-pick or manually re-apply your changes. This avoids the accumulated mess of multiple conflict resolutions and merge commits.

Cherry-pick approach: pick each of your commits and resolve conflicts one at a time. Each conflict is small because you are resolving it commit by commit.

Manual approach: copy your changed code, create a new branch, paste your changes. Sounds extreme but is often FASTER than resolving 20+ complex conflicts.

# The nuclear option: start fresh

# Step 1: Get the latest main
git fetch origin
git checkout main
git pull origin main

# Step 2: Create a fresh branch
git checkout -b feature/login-v2

# Step 3: Cherry-pick your commits one by one
git cherry-pick abc1234  # first commit
# If conflict: resolve just this one commit's conflict
git add .
git cherry-pick --continue

git cherry-pick def5678  # second commit
# Resolve conflicts for just this commit

# Step 4: Push the clean branch
git push -u origin feature/login-v2

# Close the old PR and open a new one
# The new PR has clean history, no merge commits, minimal conflicts

# Alternative: Manual re-apply (for very messy situations)
git checkout main
git checkout -b feature/login-v3
# Manually copy your code changes from the old branch
git diff main..feature/login -- src/auth/ > auth-changes.patch
git apply auth-changes.patch
# Fix any issues, commit, push
05The PR Review Culture: Speed Prevents Conflicts

Fast PR reviews prevent conflicts. If PRs are reviewed within 24 hours, conflicts are minimal. If reviews take a week, conflicts are guaranteed.

Set team expectations: PRs should be reviewed within 1 business day. Small PRs are easier and faster to review, creating a virtuous cycle.

Use draft PRs for early feedback without blocking reviewers. This catches design issues before you invest too much time.

Set limits: if a PR is open for more than 3 days, it needs to be split or escalated. The cost of slow reviews is not just waiting time — it is the conflict resolution time when the PR finally gets attention.

💡 The 24-hour review rule: Every PR should receive a first review within 24 hours. This prevents the accumulation of conflicts and keeps the team's velocity high. If you cannot review within 24 hours, at least acknowledge the PR and estimate when you will review. Communication prevents frustration.
# Setting up PR templates and automation for faster reviews

# 1. PR template (.github/PULL_REQUEST_TEMPLATE.md)
cat > .github/PULL_REQUEST_TEMPLATE.md << 'EOF'
## What
<!-- Describe the change in 1-2 sentences -->

## Why
<!-- Why is this needed? Link to issue -->

## How
<!-- Brief description of the approach -->

## Testing
<!-- How did you test this? -->

## Checklist
- [ ] Self-reviewed the code
- [ ] No console.logs or debug code
- [ ] Tests added/updated
- [ ] Documentation updated (if needed)
EOF

# 2. GitHub Actions: Auto-assign reviewers
name: Auto-assign
on:
  pull_request:
    types: [opened]
jobs:
  assign:
    runs-on: ubuntu-latest
    steps:
      - uses: kentaro-m/auto-assign-action@v1

# 3. GitHub Actions: Remind for stale PRs
name: PR reminder
on:
  schedule:
    - cron: '0 9 * * 1-5'  # 9am weekdays
jobs:
  remind:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v8
        with:
          stale-pr-message: "PR open 3+ days. Review ASAP."
          days-before-pr-stale: 3
          days-before-pr-close: -1
Long-running PRs are a systemic problem, not an individual one. If your team regularly has PRs open for weeks, the problem is in the process, not the people. Fix the system: require smaller PRs, set review SLAs, use feature flags for incomplete work, and rebase daily. One team reduced their average PR lifetime from 8 days to 1.5 days by simply requiring PRs under 300 lines. The conflict rate dropped by 90%.

Lo kar liya — Key Points:

  • ✅ Long-running PRs accumulate conflicts exponentially as the target branch diverges
  • ✅ Daily rebasing (git rebase origin/main) prevents conflicts from compounding — resolve small conflicts daily instead of massive ones at merge time
  • ✅ Small PRs (under 400 lines) are easier to review, faster to merge, and have fewer conflicts
  • ✅ Break large features into a series of small PRs: schema → API → logic → UI
  • ✅ If conflicts overwhelm a PR, start fresh: create a new branch from latest main and cherry-pick your commits
  • ✅ Fast PR reviews (within 24 hours) are the best prevention — slow reviews cause conflicts
  • ✅ Feature flags allow merging incomplete work, eliminating the need for long-lived feature branches
Course Search
Search across all chapters & stages
📖

Search the course

Type any topic — branching, stash, rebase, hooks — and jump straight to that chapter.

merge branchesgit stashundo commitrebase