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.

Stars 1
Forks 0

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):

  1. Load stack metadata from Serena memory (if available)
  2. Enumerate ALL branches with commit counts
  3. Present scope summary to user
  4. Get explicit scope approval before proceeding
  5. After completion, report status per branch

Empty rebase detection:

  • If git rebase produces 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:

  1. Create base PR with foundation (e.g., feat/auth-base)
  2. Create child PR branching from base (e.g., feat/auth-login from feat/auth-base)
  3. Each PR should be independently reviewable and mergeable
  4. Merge bottom-up: base first, then children

Stack structure:

text
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:

markdown
## 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):

  1. Wait for parent PR approval
  2. Merge parent PR into main
  3. Rebase child PR onto updated main
  4. Get child PR approved
  5. Repeat for each level in stack

Correct merge sequence:

text
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:

  1. Fetch latest changes
  2. Checkout child branch
  3. Rebase onto updated main
  4. Force push (safe for your PR branch)
shell
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):

text
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:

text
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:

shell
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:

shell
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:

shell
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 -3 and confirm the tip commit is the merge/rebase you just performed before proceeding downstream

Merging main directly into a child branch corrupts history:

shell
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:

  1. Merge parent PR first
  2. Rebase child: git rebase --onto origin/main feat/parent
  3. Force push child: git push --force-with-lease
  4. Delete parent branch after child base updated

Verify stack scope before operations:

shell
./smith-stacks/scripts/verify-stack-scope.sh 'feat/PROJ-*'

Expand your agent's capabilities with these related and highly-rated skills.

tianjianjiang/smith

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.

1 0
Explore
tianjianjiang/smith

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.

1 0
Explore
tianjianjiang/smith

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.

1 0
Explore
tianjianjiang/smith

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.

1 0
Explore
tianjianjiang/smith

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.

1 0
Explore
tianjianjiang/smith

smith-analysis

Reasoning frameworks and problem decomposition techniques. Use when planning implementation, evaluating arguments, estimating scope, decomposing complex tasks, or applying first principles thinking.

1 0
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results