Skip to content
Stacknxt Inc
github features Pull Request

Stop Waiting on Code Reviews: The Ultimate Guide to Stacked PRs

Ready to try it? Stacked PRs are basically a superpower, but they come with a specific set of Git challenges.

Rahul Woll

Rahul Woll

2 min read

Have you ever finished a feature, opened a Pull Request (PR), and then… sat there?

You know you need to build the next part of the feature, but it depends on the code you just submitted. You don’t want to dump a massive, 2,000-line PR on your senior engineer (they will inevitably hate you for it), but you also can’t afford to be blocked for two days waiting for an approval.

If this sounds familiar, you need to learn how to use Stacked PRs.

In this post, we’ll break down exactly what Stacked PRs are, how to implement them in your Git workflow, and how to avoid the common rebase traps that catch developers off guard.

What Are Stacked PRs?

Instead of cramming a massive feature into a single, unreviewable pull request, stacking is the practice of breaking your work into a sequence of smaller, dependent branches. Each branch adds a logical chunk of the feature, and each gets its own separate PR.

Because Branch B is based on Branch A (rather than main), you can keep working forward while your teammates review your code asynchronously.

Stacked Pull Request (PR) Workflow

This document provides a visual and step-by-step flow for executing Stacked PRs to keep your development unblocked.

Visual Workflow

flowchart TD
    %% Base Branching
    Main[fa:fa-code-branch main] -->|1. Branch off main| PR1_Branch(feature/1-db-schema)
    PR1_Branch -->|2. Open PR 1| PR1_Target[PR #1 Base: main]
    
    %% Stacked Branching 1
    PR1_Branch -->|3. Branch off PR 1| PR2_Branch(feature/2-api-endpoints)
    PR2_Branch -->|4. Open PR 2| PR2_Target[PR #2 Base: feature/1-db-schema]
    
    %% Stacked Branching 2
    PR2_Branch -->|5. Branch off PR 2| PR3_Branch(feature/3-frontend-ui)
    PR3_Branch -->|6. Open PR 3| PR3_Target[PR #3 Base: feature/2-api-endpoints]

    %% Review and Merge Flow
    classDef merge fill:#2ea44f,stroke:#2ea44f,color:white;
    
    PR1_Target -.->|7. Merged| Main_Updated1[main updated]:::merge
    Main_Updated1 -.->|8. Update PR 2 Base| PR2_Target_New[PR #2 Base: main]
    PR2_Target_New -.->|9. Merged| Main_Updated2[main updated]:::merge

Step-by-Step Command Flow

1. Create the Base PR (PR #1)

Branch off main for your foundational work.

git checkout main
git pull origin main
git checkout -b feature/1-db-schema
# ... write code ...
git add .
git commit -m "feat: db schema"
git push -u origin feature/1-db-schema
  • GitHub/GitLab Action: Open PR #1 and set the target/base branch to main.

2. Create the Dependent PR (PR #2)

Don’t wait for PR #1 to merge. Branch directly off feature/1-db-schema.

git checkout feature/1-db-schema
git checkout -b feature/2-api-endpoints
# ... write code ...
git add .
git commit -m "feat: api endpoints"
git push -u origin feature/2-api-endpoints
  • GitHub/GitLab Action: Open PR #2 and set the target/base branch to feature/1-db-schema.

3. Handling Code Review Updates (The Ripple Effect)

If Reviewer A requests changes on PR #1, you must update PR #1 and then cascade those changes to PR #2.

# Update PR #1
git checkout feature/1-db-schema
# ... make requested changes ...
git commit -am "fix: review comments on schema"
git push origin feature/1-db-schema

# Cascade changes to PR #2
git checkout feature/2-api-endpoints
git rebase feature/1-db-schema
git push -f origin feature/2-api-endpoints

4. Merging the Stack

When PR #1 is approved and merged into main:

  1. PR #1 is merged.
  2. Go to PR #2 in your GitHub/GitLab UI.
  3. Change the base branch of PR #2 from feature/1-db-schema to main.
  4. (Optional but recommended) Pull the latest main locally and rebase PR #2 if your team uses squash-merging.
git checkout main
git pull origin main
git rebase --onto main feature/1-db-schema feature/2-api-endpoints
git push -f origin feature/2-api-endpoints

A Real-World Use Case

Imagine you are building a new user profile dashboard. To make this work, you need to:

1. Update the database schema.

2. Build the backend API endpoints.

3. Create the frontend React components.

The Anti-Pattern (One Giant PR): You build everything on one branch (feature/user-dashboard). When you open the PR, it has 45 changed files. Your reviewer takes one look, sighs, and puts it off until Friday.

The Stacked Approach: Instead, you create three isolated but dependent branches.

  • PR 1: Database schema changes. (Easy to review, gets merged quickly).

  • PR 2 (Depends on PR 1): Backend API.

  • PR 3 (Depends on PR 2): Frontend UI.

Your reviewers get small, easily digestible chunks of code. You get to keep writing code without waiting.

How to Stack PRs (Step-by-Step)

Here is how you actually execute a stack using standard Git commands.

Step 1: Create the Base Branch

Checkout from main and make your first set of changes (e.g., the database schema).

git checkout -b feature/1-db-schema main
# Make your commits...
git commit -m "feat: update user schema"
git push origin feature/1-db-schema

Open PR #1: Base it against main.

Step 2: Stack the Next Branch

Instead of branching from main again, branch directly off your first feature branch.

git checkout -b feature/2-api-endpoints feature/1-db-schema
# Make your commits...
git commit -m "feat: add user profile API"
git push origin feature/2-api-endpoints

Open PR #2: In GitHub/GitLab, explicitly set the base of this PR to feature/1-db-schema, not main.

Step 3: Keep Climbing

Repeat the process for your frontend branch.

git checkout -b feature/3-frontend-ui feature/2-api-endpoints
# Make your commits...
git commit -m "feat: build profile dashboard UI"
git push origin feature/3-frontend-ui

Open PR #3: Base it against feature/2-api-endpoints.

The Gotchas: Potential Pitfalls & Mistakes

Stacked PRs are basically a superpower, but they come with a specific set of Git challenges.

1. The “Cascading Rebase” Nightmare

If a reviewer requests changes on PR #1, you have to update feature/1-db-schema. But now, PR #2 and PR #3 are out of sync. If you aren’t careful, you will end up with merge conflicts across your entire stack.

The Fix: You must rebase the dependent branches onto the updated base branch.

# Update the bottom of the stack
git checkout feature/1-db-schema
# ... make requested changes and commit ...

# Rebase the next branch up
git checkout feature/2-api-endpoints
git rebase feature/1-db-schema

# Rebase the top of the stack
git checkout feature/3-frontend-ui
git rebase feature/2-api-endpoints

(Pro-tip: Use git rebase --onto for more complex branch surgery if intermediate commits get messy).

2. Merging Out of Order

If you squash and merge PR #2 before PR #1, you will break the Git history of your stack. Always merge from the bottom up. Once PR #1 is merged into main, you must re-target PR #2’s base from feature/1-db-schema to main before merging it.

3. Reviewer Confusion

If reviewers don’t realize PR #3 depends on PR #2, they might get confused looking at the diffs. Always make it explicitly clear in the PR description that this is part of a stack, and link the dependent PRs.

Summary

Stacked PRs optimize for developer momentum. By breaking monolithic feature branches into small, logically sequential pieces, you reduce cognitive load for your reviewers and eliminate your own wait times.

While it requires a firmer grasp on Git rebasing, the trade-off in velocity is well worth the learning curve. If standard Git commands feel too manual for this workflow, check out CLI tools designed specifically for this, like Graphite or Git Town, which automate the tedious rebasing steps.

Ready to try it? On your next feature, try splitting your first logical chunk (like a database migration or interface definition) into its own PR, branch off it, and keep coding. Let us know how your team reacts to the bite-sized reviews!

Back to Blog
Share:

Related Posts

Hero Scroll Indicator — Desktop-Only, Hides on Scroll

Astro 's hero has an animated scroll indicator: two bouncing chevrons that fade in after the hero animation and disappear the moment you start scrolling. Here's how every part of it works.

Hans Martens
Hans Martens
2 min read
astro-rocket features ux animation

Scroll Progress Ring — A Circular Indicator on the Back-to-Top Button

Astro 's back-to-top button now has a circular SVG progress ring that fills as you scroll. It's brand-coloured, theme-aware, and runs entirely in CSS and a small inline script.

Hans Atkins
Hans Atkins
2 min read
astro-rocket features ux animation

Scroll Progress Bar — Reading Progress at a Glance

Astro now has a scroll progress bar: a thin brand-coloured line that fills as you scroll. Here's how it works, where it lives, and how to enable it on any page.

Hans Martens
Hans Martens
2 min read
astro-rocket features header ux

Follow along

Stay in the loop — new articles, thoughts, and updates.