Agent skill
smith-stacks
Stacked pull request workflows for large features. Use when creating stacked PRs, managing dependent PRs, or rebasing after parent merges. Covers stack creation, merge order, and squash merge handling.
Install this agent skill to your Project
npx add-skill https://github.com/tianjianjiang/smith/tree/main/smith-stacks
SKILL.md
Stacked Pull Requests
- Scope: Advanced stacked PR workflows and patterns for large features
- Load if: Creating stacked PRs, working on PR stacks, managing dependent PRs
- Prerequisites:
@smith-gh-pr/SKILL.md,@smith-git/SKILL.md,@smith-gh-cli/SKILL.md
CRITICAL (Primacy Zone)
- NEVER merge child PR before parent
- NEVER merge main directly into child branch
- NEVER create stacks deeper than 3-4 levels
- NEVER use squash merge for non-final PRs in a stack
Stack Scope Verification
Before stack-wide operations (rebase cascade, PR creation):
- Load stack metadata from Serena memory (if available)
- Enumerate ALL branches with commit counts
- Present scope summary to user
- Get explicit scope approval before proceeding
- After completion, report status per branch
Empty rebase detection:
- If
git rebaseproduces 0 new commits, STOP - Investigate why (already up-to-date? wrong base?)
- Report the anomaly to user before continuing
For large features, use stacked PRs to maintain atomic, reviewable changes.
When to stack:
- Feature requires 500+ lines of changes
- Multiple logical components that can be reviewed independently
- Need to unblock dependent work before full feature is ready
Creating Stacked PRs
How to stack:
- Create base PR with foundation (e.g.,
feat/auth-base) - Create child PR branching from base (e.g.,
feat/auth-loginfromfeat/auth-base) - Each PR should be independently reviewable and mergeable
- Merge bottom-up: base first, then children
Stack structure:
main
└── feat/auth-base (PR #1: models, migrations)
└── feat/auth-login (PR #2: login endpoint)
└── feat/auth-oauth (PR #3: OAuth integration)
PR description for stacked PRs:
## Stack
- **Depends on**: #123 (feat/auth-base) ← This PR requires #123 to be merged first
- **Blocks**: #125 (feat/auth-oauth) ← PR #125 depends on this PR
Field meanings:
Depends on: PRs that must merge before this one (upstream dependencies)Blocks: PRs waiting for this one to merge (downstream dependents)
Stacked PR Merge Workflow
Sequential merge order (bottom-up):
- Wait for parent PR approval
- Merge parent PR into
main - Rebase child PR onto updated
main - Get child PR approved
- Repeat for each level in stack
Correct merge sequence:
1. Merge PR #1 (feat/auth-base) → main
2. Rebase PR #2 (feat/auth-login) onto main
3. Merge PR #2 → main
4. Rebase PR #3 (feat/auth-oauth) onto main
5. Merge PR #3 → main (can squash this one)
Rebasing After Parent Merges
When a parent PR merges, child PRs must be rebased:
- Fetch latest changes
- Checkout child branch
- Rebase onto updated main
- Force push (safe for your PR branch)
git fetch origin
git checkout feat/auth-login
git rebase --onto origin/main feat/auth-base
git push --force-with-lease
Why --onto: Only transplants commits unique to child branch (commits between parent and child), avoiding duplicate commits.
Before rebase (after parent merged):
main ──●──●──●──M (parent merged as M)
\
feat/auth-login ──A──B──C (still based on old parent)
After git rebase --onto origin/main feat/auth-base:
main ──●──●──●──M
\
└──A'──B'──C' (feat/auth-login rebased)
Squash Merge with Stacked PRs
Squash merge IS allowed if you follow the branch deletion process for stacked PRs.
Merge Strategy by PR Position:
- Parent (has children): Squash OK with process, delete after child base updated
- Middle: Squash OK with process, delete after child base updated
- Final (leaf): Squash OK, immediate deletion OK
Why squash merge requires extra steps:
Squash merge creates a single commit, destroying commit ancestry. Child branches still contain parent's original commits, causing:
- Duplicate commits in child PR
- Merge conflicts when rebasing
- Git unable to recognize commits already in main
Fixing child PR after parent was squash merged:
Option 1 - Rebase with --fork-point:
git fetch origin
git checkout feat/auth-login
git rebase --onto origin/main --fork-point origin/feat/auth-base
git push --force-with-lease
Option 2 - Interactive rebase to drop parent's commits:
git checkout main && git pull
git checkout feat/auth-login
git rebase -i main
In the interactive editor, mark all commits from the parent branch as drop.
Keeping Stack Updated
When pulling changes from main into a stack, cascade updates through the stack sequentially:
git checkout feat/auth-base
git merge main
git push
git checkout feat/auth-login
git merge feat/auth-base
git push
- After each cascade step, run
git log --oneline -3and confirm the tip commit is the merge/rebase you just performed before proceeding downstream
Merging main directly into a child branch corrupts history:
git checkout feat/auth-login
git merge main
Best Practices
Good stack structure:
- Each PR is independently reviewable (clear purpose, focused changes)
- Clear dependency documentation in PR descriptions
- Commits are atomic within each level
- Bottom-up merge order maintained
Good communication:
- Document stack relationships in PR descriptions
- Update child PRs promptly after parent merges
- Notify reviewers when dependencies merge
- Explain the overall feature in parent PR
Bad practices:
- Creating stacks deeper than 3-4 levels (too complex to manage)
- Merging PRs out of order (breaks dependency chain)
- Forgetting to update child PRs after parent merge (causes conflicts)
- Using stacked PRs for unrelated changes (defeats purpose of atomicity)
@smith-gh-pr/SKILL.md- Complete GitHub PR lifecycle@smith-git/SKILL.md- Commits, branches, rebase@smith-gh-cli/SKILL.md- GitHub CLI commands
ACTION (Recency Zone)
Merge stacked PRs bottom-up:
- Merge parent PR first
- Rebase child:
git rebase --onto origin/main feat/parent - Force push child:
git push --force-with-lease - Delete parent branch after child base updated
Verify stack scope before operations:
./smith-stacks/scripts/verify-stack-scope.sh 'feat/PROJ-*'
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
smith-style
File naming, path standards, and conventional commits. Use when naming files, creating branches, writing commit messages, or setting up new projects. Covers underscore vs hyphen conventions, commit format, and branch naming patterns.
smith-python
Python development with uv, pytest, ruff, and type hints. Use when writing Python code, running tests, managing Python packages, or working with virtual environments. Covers import organization, type hints, pytest patterns, and environment variables.
smith-principles
Fundamental coding principles (DRY, KISS, YAGNI, SOLID, HHH). Use when starting any development task, evaluating implementation approaches, or reviewing code quality. Always active as foundation for all development decisions.
smith-nuxt
Nuxt 3 development patterns including auto-import stubbing for tests, environment variable conventions, and middleware testing. Use when working with Nuxt projects, testing Nuxt components/middleware, or configuring Nuxt environment variables.
smith-plan
Plan tracking protocol (portable). Progress tracking with checkboxes, iteration workflow, completion/blocker signals. Use when executing multi-step plans, tracking task progress, or working from plan files. IMPORTANT - Always update the plan file after completing tasks.
smith-analysis
Reasoning frameworks and problem decomposition techniques. Use when planning implementation, evaluating arguments, estimating scope, decomposing complex tasks, or applying first principles thinking.
Didn't find tool you were looking for?