Install in seconds
Install this skill
Copy the command and run it in your terminal. You can review the source before installing.
terminal
git clone https://github.com/crbnos/carbon

Works with Git. The repository opens in your current directory.

✂️
QualityTypeScript

PR Splitter

by crbnos

Splits a large or messy PR into smaller, reviewable stacked or parallel PRs without losing any work. Extracts changes non-interactively, verifies each PR independently, and tracks drift from review feedback.

2.3K stars326 forksAdded 2026/07/21
businesserpleanmanagementmanufacturingmcp-servermespostgresqlqmsreact-routersupabasetypescript

Documentation

README

pr-splitter — break a big PR into reviewable pieces

The original branch is source material, never a casualty: snapshot it, build smaller PRs from it deliberately, and keep a local ledger of what went where.

Announce at start: "Using the pr-splitter skill — splitting {branch} into smaller PRs."

Never use interactive git commands (git restore -p, git add -i, git rebase -i) — they hang in this environment. Every extraction below is non-interactive.

Step 1: Snapshot before touching anything

git status --porcelain        # must be empty; if not, STOP — commit or stash first
BASE=$(git merge-base origin/main HEAD)
git branch backup/original-$(git branch --show-current)

Do not delete or rewrite the original branch until the split has fully shipped.

Step 2: Inventory the original PR

git diff --stat $BASE...HEAD
git diff --name-only $BASE...HEAD
git log --oneline $BASE..HEAD

Classify every changed file into exactly one review unit:

Unit Examples
prep / refactor renames, extractions, no behavior change
API / type changes signatures, models, generated types
behavior the actual feature/fix logic
tests new or changed tests
docs / metadata AGENTS.md, docs, changelogs
generated / lockfiles pnpm-lock.yaml, generated types

Step 3: Create the scratchpad

Write .ai/scratch/pr-split.md (gitignored — never commit it):

# PR split — {original branch}
Backup: backup/original-{branch} · Base: {BASE sha}

## Planned PRs
1. {branch-name} — scope: … — files/hunks: … — verify: … — status: …

## Remaining original intent
- …

## Drift notes (date / branch / what changed and why)
- …

Step 4: Choose the split shape

Situation Shape
Later work depends on earlier work Stacked PRs (each branched off the previous)
Changes are truly independent Parallel PRs off main
One shared prep change unlocks independent work Foundation PR + parallel follow-ups
Unsure Stacked — dependency mistakes surface as conflicts, not broken builds

Rules: never separate tests from the code they verify; never split one behavior across two PRs by file boundary; each PR must build and pass its tests alone.

Step 5: Extract non-interactively

Start each PR from the correct base (main, or the previous PR in the stack):

git checkout -b {pr-branch} {base}

Whole files (the file belongs entirely to this PR):

git checkout backup/original-{branch} -- path/to/file.ts

Part of a file (the file mixes changes for different PRs):

git diff {base} backup/original-{branch} -- path/to/file.ts > .ai/scratch/extract.patch
# Edit .ai/scratch/extract.patch: keep the file header lines (---/+++),
# DELETE every @@-hunk that belongs to a different PR, keep the hunks you want.
git apply .ai/scratch/extract.patch

If git apply fails (context mismatch), do not fight it: open the file and make the wanted changes by hand, using the patch as the reference. Then delete the patch file.

Commit each extraction with a conventional message and check it off in the scratchpad, noting exactly which files/hunks moved.

Step 6: Verify each PR independently

For every PR branch, before opening it:

pnpm exec biome check --write --no-errors-on-unmatched <changed paths>
pnpm exec turbo run typecheck --filter=<pkg>    # per touched package, never whole-repo
pnpm --filter <pkg> test

A PR that only compiles on top of an unmerged sibling is stacked — say so in its description and set its GitHub base branch accordingly.

Step 7: PR descriptions

## Summary
PR {N} of {M} split from {original branch}.

## Scope
- …

## Intentionally excluded (follow-up PRs)
- …

## Verification
- {commands run + results}

Keep the detailed extraction ledger in .ai/scratch/pr-split.md, not in PR bodies.

Step 8: Manage drift as reviews land

  • Reviewer-approved changes are the new source of truth — when an earlier PR changes, rebase its dependents onto it and resolve conflicts in favor of the reviewed direction, never blindly back toward the original branch.
  • After any rebase/force-push: git range-diff {old-tip}...{new-tip} and summarize meaningful differences for reviewers.
  • Periodically diff the stack against the backup to find remaining intent (work not yet shipped in any PR) — not to force byte-for-byte equality.
  • Record every intentional divergence in the scratchpad's drift notes.

Done when

  • Every hunk of git diff $BASE...backup/original-{branch} is either shipped in a PR or explicitly listed in the scratchpad as dropped (with a reason)
  • Each PR builds and passes its scoped gates independently
  • Tests shipped in the same PR as the code they verify
  • Backup branch still intact

Failure modes to avoid

Splitting by file when behavior spans files · extracting tests without their code · a follow-up PR that doesn't compile · force-pushing without a range-diff summary · deleting the backup early · resolving stack conflicts by reverting reviewer feedback.

More from crbnos

Other Claude Code skills by this author in the directory.