Decompose large PRs into a DAG of small, reviewable PRs
Vibe coding with AI assistants can produce massive PRs that no one wants to review. A 2,000 line PR with changes across dozens of files is a review bottleneck: teammates skim it, rubber stamp it, or just ignore it. pr-split turns that monolith into a set of focused, bite-sized PRs your team can actually review with confidence. Each sub-PR has a clear purpose, minimal scope, and explicit dependencies, so reviewers know exactly what changed and why.
pr-split takes a large pull request (local branch, fork PR number, or user:branch), sends the diff to an LLM for analysis, and produces a split plan: a set of smaller, focused PRs arranged in a dependency DAG. Each sub-PR gets its own branch, commit, and GitHub PR targeting the correct base.
# With uv (recommended)
uv tool install pr-split
# With pip
pip install pr-split- Python 3.12+
- GitHub CLI (
gh) authenticated viagh auth login ANTHROPIC_API_KEYorOPENAI_API_KEYenvironment variable set when using thellmpartition backend
pr-split split feature-branch --base mainpr-split split '#42' --base mainpr-split split someuser:feature-branch --base mainpr-split split feature-branch --base main --dry-run| Flag | Default | Description |
|---|---|---|
--base |
main |
Base branch for the diff |
--min-loc |
unset | Optional minimum diff lines per sub-PR |
--max-loc |
400 |
Maximum target diff lines per sub-PR |
--strict-loc-bounds |
false |
Exit instead of proceeding when the final plan violates configured LOC bounds |
--priority |
orthogonal |
Grouping priority (orthogonal or logical) |
--chunk-strategy |
dynamic_programming |
Large-diff chunking strategy (dynamic_programming or greedy) |
--partition-strategy |
llm |
Hunk-to-PR partition backend (llm, graph, or cp_sat) |
--dry-run |
false |
Preview plan and save to .pr-split/plan.json without creating branches or PRs |
pr-split statusShows a table with each sub-PR's ID, title, branch, PR number, live state (OPEN/CLOSED/MERGED), and review decision (Approved, Changes Requested, etc.) queried directly from GitHub.
pr-split mergeWalks the dependency DAG and merges each PR in topological order. Skips already-merged, closed, draft, review-required, or changes-requested PRs. Stops if a merge fails or a dependency wasn't merged to prevent out-of-order merges.
Use --auto to queue merges behind CI checks (uses gh pr merge --auto):
pr-split merge --autoUse --notify to POST merge results to a webhook URL (e.g. Slack, Discord):
pr-split merge --notify https://hooks.slack.com/...pr-split executeCreates branches and PRs from a previously saved --dry-run plan. Uses the saved diff and merge base for consistency — safe even if the dev branch has changed since the dry run.
After the plan is displayed, an interactive editor lets you adjust the plan before confirming:
edit> show pr-1 # inspect a group's assignments
edit> move src/foo.py:2 pr-1 pr-2 # move a hunk between groups
edit> plan # redisplay the plan table
edit> done # proceed (default — just press Enter)
edit> abort # cancel
The plan is re-validated after editing to catch empty groups or coverage gaps.
Create .pr-split/template.md to customize the body of each generated PR using placeholders:
{description}
### Files
{files}
**Stats:** +{added}/-{removed} ({loc} lines)
{dag}Available placeholders: {description}, {files}, {added}, {removed}, {loc}, {dependencies}, {dag}, {id}, {title}.
Running split again when a plan already exists will prompt you to clean up existing branches and PRs before re-planning. Dry-run plans are silently overwritten.
pr-split cleanCloses all split PRs, deletes their branches (local and remote), and removes the plan file.
Settings can be set via environment variables with the PR_SPLIT_ prefix:
| Variable | Default | Description |
|---|---|---|
PR_SPLIT_PROVIDER |
anthropic |
LLM provider (anthropic or openai) |
ANTHROPIC_API_KEY |
(required for Anthropic) | Anthropic API key |
OPENAI_API_KEY |
(required for OpenAI) | OpenAI API key |
PR_SPLIT_MODEL |
auto per provider | Model name (defaults to best available model for the chosen provider) |
PR_SPLIT_MIN_LOC |
unset | Optional minimum target diff lines |
PR_SPLIT_MAX_LOC |
400 |
Default maximum target diff lines |
PR_SPLIT_STRICT_LOC_BOUNDS |
false |
Fail if the final plan violates configured LOC bounds |
PR_SPLIT_PRIORITY |
orthogonal |
Default grouping priority |
PR_SPLIT_CHUNK_STRATEGY |
dynamic_programming |
Large-diff chunking strategy |
PR_SPLIT_PARTITION_STRATEGY |
llm |
Hunk-to-PR partition backend |
PR_SPLIT_WEBHOOK_URL |
(none) | Webhook URL for merge notifications |
pr-split now separates two optimization layers:
- Chunking: for diffs that exceed the model context window,
dynamic_programmingchooses chunk boundaries to avoid splitting the same file when possible.greedykeeps the previous first-fit behavior. - Partitioning:
llmpreserves the original semantic planner,graphuses deterministic affinity-based grouping, andcp_satuses an optimization model to balance group count, LOC, and cohesion.
The cp_sat backend requires the optional ortools package to be installed in the runtime environment.
For a deeper explanation of the planning model, optimization methods, scoring, and research directions, see METHODOLOGY.md.
- Extracts the merge-base diff between your branch and the base (same view as GitHub's PR page)
- Sends the diff to the configured backend (LLM, graph, or CP-SAT), which groups hunks into logical sub-PRs with dependency ordering
- Validates the plan: full coverage (every hunk assigned exactly once), no cycles, no merge conflicts between independent groups
- Shows you the plan (table + dependency tree) with an optional interactive editor to move hunks between groups
- Creates branches, commits, pushes, and opens GitHub PRs — materialization and push/PR creation run in parallel using git worktrees. Use
--dry-runto save the plan for later execution withexecute - For diffs exceeding the model's context window, uses the configured chunking strategy and processes chunks sequentially while carrying forward the group catalog across chunks
status,merge, andcleancommands are available to track progress, merge PRs in dependency order, or clean up branches and PRs

