0x55aa
โ† Back to Blog

Why Your Pull Request Got Ignored (And How to Get It Merged) ๐Ÿ”€โœจ

โ€ข19 min read

Why Your Pull Request Got Ignored (And How to Get It Merged) ๐Ÿ”€โœจ

Real talk: I once submitted a PR that added a feature I spent TWO WEEKS building. Clean code. Tests passing. Documentation updated. I was so proud! And then... nothing. Weeks went by. No comments. No review. Just silence. ๐Ÿ˜ญ

Plot twist: The maintainer merged someone else's simpler PR that solved the same problem in 3 days. Mine got closed with "duplicate."

As a full-time developer who contributes to open source AND maintains Laravel/security projects, I've been on BOTH sides. I've ghosted PRs. I've HAD my PRs ghosted. And let me tell you - there's a SECRET FORMULA to getting PRs merged, and most contributors don't know it! ๐ŸŽฏ

Let me show you why your PR is sitting there collecting dust - and how to fix it! ๐Ÿ’ช

The Uncomfortable Truth About Pull Requests ๐Ÿ’ฃ

What you think happens when you open a PR:

You: *opens amazing PR*
Maintainer: "This is brilliant! Let me merge immediately!"
*PR merged in 10 minutes*
*Champagne and celebration!* ๐Ÿพ

What actually happens:

You: *opens PR*
Maintainer: *has 47 other PRs to review*
Maintainer: *has full-time job*
Maintainer: *has family, life, burnout*
Maintainer: *glances at your PR*
Maintainer: "This needs work... I'll come back to it"
Maintainer: *never comes back*
Your PR: *dies alone in page 3* ๐Ÿ’€

The stats that hurt:

  • 68% of PRs to popular open source projects never get merged
  • 54% get closed without any feedback
  • 83% of contributors give up after first PR is ignored
  • The average PR review time is 2-4 weeks (if it gets reviewed at all!)
  • ONE well-crafted PR has an 85% merge rate vs. 15% for rushed PRs!

Translation: Most PRs die in the queue. Yours is probably one of them! ๐Ÿ˜ฌ

But hey! You're reading this, which means you're about to become part of the 15% whose PRs actually GET MERGED! ๐ŸŽ‰

The PR Spectrum (Where Does Yours Fall?) ๐ŸŽฏ

The "Ignored Forever" PR โŒ

The classic:

Title: "Update"

Changes:
- 47 files changed
- No description
- No tests
- Breaking changes
- Fixes issue that doesn't exist

Comment: "I fixed some stuff. Pls merge."

Why maintainers ghost it:

  • What does this PR do? Who knows!
  • Does it break anything? Probably!
  • Is it tested? Nope!
  • Is there an issue discussing this? Nope!
  • Do I have time to figure this out? NOPE!

Maintainer's reaction: closes tab and hopes someone else deals with it

Your PR gets: Ignored until auto-closed after 90 days! ๐Ÿ’€

The "Almost There" PR ๐Ÿ“ฆ

The frustrating one:

Title: "Add dark mode toggle"

Changes:
- Actual feature that works!
- Some tests
- Basic docs
- But... conflicts with main
- And... doesn't follow code style
- And... modifies 15 files that didn't need changes

Why it sits there:

  • Maintainer thinks: "This is good but needs work"
  • Maintainer comments: "Please rebase and fix conflicts"
  • You: never respond
  • Or you: force push and break everything
  • Maintainer: too tired to keep following up

Maintainer's reaction: "I'll wait for them to fix it... waits forever"

The "INSTANT MERGE" PR โœจ (BE THIS ONE!)

The gold standard:

Title: "feat: Add dark mode toggle (fixes #234)"

Description:
Implements dark mode toggle as discussed in issue #234.

**Changes:**
- Added toggle component in Settings
- Persists preference to localStorage
- Updates 3 theme-dependent components
- Added tests (coverage: 95%)
- Updated docs with screenshots

**Testing:**
- โœ… Tested on Chrome, Firefox, Safari
- โœ… Tested with light/dark OS preferences
- โœ… All existing tests passing
- โœ… No breaking changes

**Screenshots:**
[Before/After images]

**Checklist:**
- โœ… Rebased on latest main
- โœ… Follows code style guide
- โœ… Documentation updated
- โœ… Tests added and passing
- โœ… No merge conflicts

Why this is PERFECT:

  • โœ… Links to existing issue (shows it's wanted!)
  • โœ… Clear description of what/why
  • โœ… Lists all changes explicitly
  • โœ… Has tests and docs
  • โœ… Provides proof it works
  • โœ… Follows checklist
  • โœ… Ready to merge RIGHT NOW

Maintainer's reaction: "This is BEAUTIFUL! clicks merge button immediately" ๐Ÿ˜

Your PR gets: Merged same day! Then featured in release notes! ๐ŸŽ‰

The 7 Deadly Sins of Pull Requests ๐Ÿ’€

Sin #1: The "No Issue" PR

The crime:

You: *spends week building feature*
You: *opens PR*
Maintainer: "We don't need this feature"
You: "But I already built it!" ๐Ÿ˜ญ
Maintainer: *closes PR*

The fix:

You: "Hey! Would you accept a PR that adds feature X?"
Maintainer: "No, that's out of scope for this project"
You: "Thanks for saving me a week!" โœ…

OR

You: "Hey! Would you accept a PR that adds feature X?"
Maintainer: "Yes! Please open an issue first to discuss approach"
You: *opens issue*
You: *discusses design*
You: *gets approval*
You: *builds it*
You: *PR gets merged!* ๐ŸŽ‰

The rule: NEVER code before discussing! Always open an issue first! ๐ŸŽฏ

In the security community, we ALWAYS discuss vulnerabilities before submitting patches. Same principle applies to features - get buy-in FIRST! ๐Ÿ”’

Sin #2: The "Everything and the Kitchen Sink" PR

The crime:

Changes:
- Added feature X
- Refactored unrelated code Y
- Updated dependencies
- Reformatted 50 files
- Changed code style
- Fixed typos in README
- And... 47 other things

Why maintainers hate it:

  • Can't review 47 changes at once!
  • Which change broke tests?
  • Can't merge feature X without accepting all other changes!
  • Risk of bugs increases exponentially!

The fix:

PR #1: Add feature X (5 files)
PR #2: Update dependencies (1 file)
PR #3: Fix README typos (1 file)

Each PR: Small, focused, easy to review!
Merge rate: ๐Ÿ“ˆ๐Ÿ“ˆ๐Ÿ“ˆ

The rule: ONE PR = ONE change! Multiple changes = Multiple PRs! ๐ŸŽฏ

Balancing work and open source taught me this: I have 30 minutes for reviews. A focused 5-file PR? I can review it. A 50-file chaos PR? That's next month's problem! โฐ

Sin #3: The "Style Guide? What Style Guide?" PR

The crime:

// Project uses semicolons
const user = getUser();

// Your PR:
const user = getUser()  // No semicolon!

// Project uses 2 spaces
function foo() {
  return bar
}

// Your PR:
function foo() {
    return bar  // 4 spaces!
}

Why it matters:

  • Linter fails! โŒ
  • CI fails! โŒ
  • Maintainer has to manually fix! ๐Ÿ˜ค
  • OR reject your PR! ๐Ÿ’€

The fix:

# BEFORE coding, run:
npm run lint  # Fix any issues!
npm run format  # Auto-format code!
npm test  # Ensure tests pass!

# Many projects have .editorconfig
# Let your IDE use it!

# Check for CONTRIBUTING.md
# It has the rules!

The rule: Match the existing code style! Use the project's linter! Run tests BEFORE pushing! ๐ŸŽฏ

Sin #4: The "Trust Me Bro" PR (No Tests)

The crime:

Title: "Fix critical bug in authentication"

Changes:
- Modified core auth logic
- No tests added
- "Trust me, it works!"

Maintainer's thought process:

"Does this actually fix the bug?" - Don't know
"Does this break anything else?" - Don't know
"How do I verify this works?" - Don't know
"Should I merge this?" - NOPE!

The fix:

Title: "Fix critical bug in authentication (fixes #123)"

Changes:
- Modified auth logic (src/auth.js)
- Added regression test (tests/auth.test.js)
- Verified fix works with test
- All existing tests still passing

Test output:
โœ“ should reject invalid tokens (NEW TEST!)
โœ“ should accept valid tokens (existing)
โœ“ should handle expired tokens (existing)

The rule: If you fix a bug, add a test that would have caught it! If you add a feature, test that feature! No tests = No merge! ๐ŸŽฏ

In my Laravel work, I learned this the hard way: "Works on my machine" means nothing. Tests prove it works everywhere! ๐Ÿงช

Sin #5: The "Good Luck Merging This" PR (Conflicts!)

The crime:

Your PR: *based on main from 3 weeks ago*
Main branch: *has 47 commits since then*
Your PR: *conflicts in 12 files*

Maintainer: "Please rebase and resolve conflicts"
You: *never responds*
Or worse: You: "Can you merge it for me?" ๐Ÿ˜ฌ

The fix:

# Keep your PR up to date!

# Every few days:
git checkout main
git pull upstream main
git checkout your-feature-branch
git rebase main

# Resolve conflicts as you go
# Not all at once at the end!

# Force push (YOUR branch only!)
git push --force-with-lease

# Now your PR is clean! โœ…

The rule: YOU own your PR! YOU keep it up to date! YOU resolve conflicts! Maintainers don't have time to fix your merge conflicts! ๐ŸŽฏ

Sin #6: The "Drive-By" PR (Then Ghost)

The crime:

Day 1: You open PR
Day 2: Maintainer comments: "Can you add tests?"
Day 3-365: *crickets* ๐Ÿฆ—

OR

Day 1: You open PR
Day 2: Maintainer comments: "Looks good! Just fix the linting"
Day 3: You force-push completely different code
Day 4: Maintainer: "Wait, what? This broke everything!" ๐Ÿ˜ฑ

The fix:

Be responsive!
โœ… Check GitHub notifications daily
โœ… Respond to comments within 48 hours
โœ… If you need time, say so: "Working on it, will update by Friday!"
โœ… If you can't finish, say so: "I don't have time anymore, feel free to take over"
โœ… When you make changes, comment what you changed

Be considerate!
โœ… Don't force-push without explaining
โœ… Don't disappear mid-review
โœ… Don't make major changes without discussion
โœ… Communication is KEY!

The rule: Maintain your PR like you maintain your code! Stay engaged until it's merged! ๐ŸŽฏ

Sin #7: The "Reinvent Everything" PR

The crime:

Issue: "The login button is 2px too small"

Your PR:
- Rewrote entire authentication system
- Switched from JWT to sessions
- Refactored the whole frontend
- Added 47 new dependencies
- Changed database schema
- "Also fixed the button size!" ๐ŸŽ‰

Why maintainers cry:

  • Asked for 2px change, got 2000 lines!
  • Now they have to review a MASSIVE rewrite!
  • Risk of bugs EVERYWHERE!
  • Probably won't merge ANY of it!

The fix:

Issue: "The login button is 2px too small"

Your PR:
- Changed button CSS from 18px to 20px
- That's it!
- 1 file, 1 line, 1 change! โœ…

Maintainer: "Perfect!" *merges immediately*

The rule: Solve the ACTUAL problem! Don't over-engineer! Simplicity wins! ๐ŸŽฏ

The "How to Get Your PR Merged" Checklist โœ…

BEFORE you start coding:

โ–ก Is there an existing issue? If not, open one!
โ–ก Did maintainer confirm they want this? Get approval first!
โ–ก Did you discuss the approach? Get agreement on design!
โ–ก Did you check for duplicate PRs? Don't waste time!
โ–ก Did you read CONTRIBUTING.md? Follow the rules!
โ–ก Did you check the style guide? Match the style!

WHILE you're coding:

โ–ก Are you making ONE focused change? Not 47 changes!
โ–ก Are you following code style? Linter should pass!
โ–ก Are you writing tests? Code + tests = mergeable!
โ–ก Are you updating docs? Docs = helps users!
โ–ก Are you keeping commits clean? Meaningful commit messages!
โ–ก Are you rebasing regularly? Stay up to date!

BEFORE you open the PR:

โ–ก Does the linter pass? npm run lint
โ–ก Do all tests pass? npm test
โ–ก Did you test manually? Does it actually work?
โ–ก Is your branch up to date? Rebase on latest main!
โ–ก Are there merge conflicts? Resolve them first!
โ–ก Did you write a good description? Explain what/why!

AFTER you open the PR:

โ–ก Did you link to the issue? "Fixes #123"
โ–ก Did you add screenshots/demos? Show it works!
โ–ก Did you request review? Tag maintainers if appropriate!
โ–ก Are you responsive? Check notifications daily!
โ–ก Did CI pass? Fix any failing checks!
โ–ก Did you address feedback? Respond to comments!

The Perfect PR Template ๐Ÿ“‹

Use this for your next PR:

## Description
[Brief description of what this PR does]

Fixes #[issue number]

## Changes
- [Specific change 1]
- [Specific change 2]
- [Specific change 3]

## Type of Change
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would break existing functionality)
- [ ] Documentation update

## Testing
- [ ] Tested locally
- [ ] All existing tests passing
- [ ] New tests added for new functionality
- [ ] Tested in multiple browsers/environments (if applicable)

## Screenshots (if applicable)
[Add screenshots showing the change]

## Checklist
- [ ] Code follows the style guide
- [ ] Self-reviewed my own code
- [ ] Commented code where needed
- [ ] Updated documentation
- [ ] No new warnings
- [ ] Added tests that prove fix/feature works
- [ ] New and existing tests pass locally
- [ ] Rebased on latest main
- [ ] No merge conflicts

## Additional Context
[Any additional information reviewers should know]

Copy this! Use it! Watch your merge rate ๐Ÿ“ˆ!

Real Examples: Good vs. Bad PRs ๐ŸŽ“

Example #1: Bug Fix

โŒ Bad PR:

Title: "Fix"

Description:
Fixed a bug

Files changed: 15
Commits: "fix", "fix2", "fix3", "actually fixed", "real fix"
Tests: None

โœ… Good PR:

Title: "fix: Prevent null pointer exception in user profile (fixes #456)"

Description:
The user profile page crashes when a user has no avatar set.
This PR adds null checks and a default avatar fallback.

**Changes:**
- Added null check in UserProfile.tsx (line 45)
- Added default avatar constant (src/constants.ts)
- Added regression test (tests/UserProfile.test.tsx)

**Root Cause:**
The component assumed avatar URL always exists, but new users
don't have avatars yet.

**Testing:**
- โœ… Tested with user with avatar (works)
- โœ… Tested with user without avatar (shows default)
- โœ… All existing tests passing
- โœ… Added test to prevent regression

**Before:**
[Screenshot showing crash]

**After:**
[Screenshot showing default avatar]

Fixes #456

Why the good one gets merged:

  • โœ… Clear problem statement
  • โœ… Explains root cause
  • โœ… Shows testing was done
  • โœ… Has screenshots
  • โœ… Links to issue
  • โœ… Includes regression test
  • โœ… Ready to merge NOW

Example #2: New Feature

โŒ Bad PR:

Title: "New feature"

Description:
Added dark mode

Files changed: 73
Lines: +2847, -1923
Tests: None
Conflicts: Yes
Style issues: Yes

โœ… Good PR:

Title: "feat: Add dark mode toggle in settings (fixes #123)"

Description:
Implements dark mode as discussed in issue #123 and design doc.

**Changes:**
- Added ThemeProvider wrapper (src/contexts/ThemeContext.tsx)
- Added toggle in Settings page (src/pages/Settings.tsx)
- Updated 8 components to use theme colors
- Persists preference to localStorage
- Detects OS theme preference on first load
- Added tests (coverage: 93%)
- Updated README with new feature

**Design Decisions:**
- Used CSS variables for easy theming
- Toggle in Settings (not navbar) per feedback in #123
- Persists to localStorage for consistency across sessions
- Falls back to OS preference if user hasn't chosen

**Testing:**
- โœ… Tested on Chrome, Firefox, Safari
- โœ… Tested with light/dark OS preferences
- โœ… Tested localStorage persistence
- โœ… All components render correctly in both themes
- โœ… No breaking changes
- โœ… All existing tests still pass

**Screenshots:**
Light mode: [screenshot]
Dark mode: [screenshot]
Toggle UI: [screenshot]

**Demo:**
[Loom video showing feature working]

Fixes #123

Why this gets merged fast:

  • โœ… Feature was pre-approved (issue #123)
  • โœ… Clear implementation details
  • โœ… Explains design decisions
  • โœ… Comprehensive testing
  • โœ… Visual proof it works
  • โœ… No breaking changes
  • โœ… Documentation updated
  • โœ… Maintainer can merge with confidence

How Maintainers ACTUALLY Prioritize PRs ๐ŸŽฏ

Secret formula from maintainer perspective:

High Priority (Merge Fast! โšก):

โœ… Small focused changes (< 100 lines)
โœ… Fixes critical bugs
โœ… Has tests
โœ… No conflicts
โœ… Responsive contributor
โœ… Follows all guidelines
โœ… Linked to approved issue

Merge time: Hours to days

Medium Priority (Review Eventually ๐Ÿ“…):

โš ๏ธ Larger changes (100-500 lines)
โš ๏ธ New features (need more review)
โš ๏ธ Missing some tests
โš ๏ธ Contributor less active
โš ๏ธ Needs minor changes

Merge time: Weeks

Low Priority (Dies in Queue ๐Ÿ’€):

โŒ Massive changes (> 500 lines)
โŒ No linked issue
โŒ No tests
โŒ Merge conflicts
โŒ Doesn't follow style
โŒ Breaking changes
โŒ Contributor ghosted
โŒ Unclear what it does

Merge time: Never

Translation: Make your PR HIGH PRIORITY! It's not about quality of code - it's about EASY TO REVIEW! ๐ŸŽฏ

Balancing work and open source taught me: I review PRs at night after work. A clean, small, well-documented PR? I'll merge it before bed. A messy, large, confusing PR? That's "someday" pile! ๐Ÿ“š

The Contributor/Maintainer Relationship ๐Ÿค

Remember: Open source maintainers are:

  • โœ… Volunteers (usually!)
  • โœ… Busy with jobs/life
  • โœ… Often burnt out
  • โœ… Drowning in notifications
  • โœ… Juggling 47 PRs
  • โœ… Trying their best!

Your job as contributor:

  • โœ… Make their life EASIER
  • โœ… Submit mergeable PRs
  • โœ… Be responsive and polite
  • โœ… Take feedback gracefully
  • โœ… Don't take silence personally
  • โœ… Respect their time!

The golden rule:

Would YOU want to review this PR at 10pm after a long day?

If no โ†’ Improve it!
If yes โ†’ Ship it! ๐Ÿš€

What To Do When Your PR Is Ignored ๐Ÿ˜”

Week 1: Be patient

Maintainers are busy! Give them time!
Don't ping immediately!

Week 2: Gentle nudge

"Hey! Just wanted to follow up on this PR.
Let me know if you need anything from my end! ๐Ÿ˜Š"

Week 3: Check if stale

"Should I rebase this on latest main?
Happy to update if needed!"

Week 4: Offer to help

"I noticed there are a lot of PRs.
Can I help with reviews or anything?"

Month 2: Consider alternatives

- Fork and maintain yourself?
- Find different project?
- Become co-maintainer?
- Accept it might not get merged?

Reality check:

  • Sometimes PRs don't get merged (not personal!)
  • Sometimes projects are effectively unmaintained
  • Sometimes your feature isn't wanted
  • Sometimes maintainer quit but hasn't said so
  • That's open source! ๐Ÿคทโ€โ™‚๏ธ

The Bottom Line ๐Ÿ’ก

Your PR gets ignored because you made it HARD to merge!

What you learned today:

  1. Always open an issue BEFORE coding
  2. One PR = One focused change
  3. Follow the style guide religiously
  4. Add tests (non-negotiable!)
  5. Keep your branch up to date
  6. Stay responsive to feedback
  7. Use the perfect PR template
  8. Make maintainer's job EASY
  9. Small PRs merge faster than big ones
  10. Your attitude matters as much as your code!

The truth:

PRs that get merged:

  • โœ… Small and focused
  • โœ… Pre-approved (linked issue)
  • โœ… Follow all guidelines
  • โœ… Have tests and docs
  • โœ… No conflicts
  • โœ… Responsive contributor
  • โœ… Professional description
  • โœ… Easy to review and merge! ๐ŸŽ‰

PRs that die in the queue:

  • โŒ Large and sprawling
  • โŒ No prior discussion
  • โŒ Ignore guidelines
  • โŒ No tests
  • โŒ Merge conflicts
  • โŒ Ghost contributor
  • โŒ "Trust me bro" description
  • โŒ Nightmare to review! ๐Ÿ’€

Which are YOU submitting? ๐Ÿค”

Your Action Plan ๐Ÿš€

Right now:

  1. Review your open PRs
  2. Are they following these rules?
  3. Update descriptions to be clearer
  4. Respond to any pending feedback
  5. Rebase and fix conflicts

Next PR:

  1. Open issue first (get approval!)
  2. Make ONE focused change
  3. Write tests
  4. Follow style guide
  5. Use the perfect PR template
  6. Stay engaged until merged

Long term:

  1. Build reputation as great contributor
  2. Write PRs maintainers LOVE to merge
  3. Eventually become trusted contributor
  4. Maybe become maintainer yourself!
  5. Pay it forward! ๐Ÿ’š

Resources & Tips ๐Ÿ“š

Before contributing:

  • Read CONTRIBUTING.md
  • Check CODE_OF_CONDUCT.md
  • Review existing PRs (learn patterns!)
  • Join project Discord/Slack
  • Introduce yourself!

Tools that help:

  • GitHub CLI (gh pr create)
  • Linters (follow the rules!)
  • Test runners (verify it works!)
  • Pre-commit hooks (catch issues early!)

Learning resources:

My experience: Check my GitHub for examples of PRs I've submitted (both merged and rejected - learn from both!).

Final Thoughts ๐Ÿ’ญ

The uncomfortable truth:

Most contributors blame maintainers for ignoring PRs. But often, it's because the PR is HARD TO MERGE. Not bad code - just hard to review, hard to test, hard to trust!

The good news:

YOU control whether your PR gets merged! It's not about connections or luck. It's about making mergeable PRs!

5 minutes improving your PR can mean the difference between:

  • โœ… Merged in a day
  • โŒ Ignored forever

In the security community, we say: "Make it easy to say yes." Same with PRs - make it SO EASY to merge that maintainers can't resist! ๐ŸŽฏ

Here's my challenge:

Right now, look at your last PR that didn't get merged. Be honest - did you follow the rules in this post? Would YOU want to review that PR?

Questions to ask yourself:

  • Did I discuss before coding? (Or surprise them?)
  • Is it focused? (Or kitchen sink?)
  • Does it have tests? (Or "trust me bro"?)
  • Is it up to date? (Or conflict city?)
  • Am I being responsive? (Or ghosting?)

Your move! โ™Ÿ๏ธ


Want to improve your OSS contributions? Connect with me on LinkedIn - I'm always sharing tips!

Check out my PRs! See examples on my GitHub - learn from successes AND failures!

Now go write PRs that GET MERGED! ๐Ÿ”€โœจ


P.S. To maintainers: If you're drowning in PRs, it's okay to close stale ones! Better to close with explanation than leave contributors hanging forever! ๐Ÿ’š

P.P.S. Remember: Every merged PR is a WIN for open source! You're making software better for everyone! Keep contributing! Don't get discouraged! The community needs YOU! ๐ŸŒŸ