v0.3.0 — JSON output, shell completions, AI features →

Stacked diffs
that stay in sync.

Turn a big branch into a reviewable stack with sdf split, or build one from scratch and keep it synced with sdf sync — with optional Claude-powered conflict resolution.

New to the workflow? Read what stacked diffs are and when to use them.

Diagram of a three-layer stacked pull request flow where PR #142 merges first, then SDF sync rebases PR #143 and PR #144 and updates their GitHub base targets.
Example stack lifecycle: merge upstream, then run sdf sync to propagate updates.
$ brew install pavelpascari/tap/sdf

Also available via go install and binary download — Linux, macOS, Windows

The pain of stacked PRs — solved

× Manual cascade rebasing

✓ One command rebases every downstream branch after an upstream PR merges.

× PR base drift on GitHub

✓ PR bases are updated during sync to match the real topology.

× Losing track of dependencies

✓ Stack topology tracked in .sdf/ with automatic navigation links in every PR description.

Everything stacked diffs need

A thin layer built on git and gh. No servers, no extra auth — just the tools you already use, working together.

✂

AI branch splitting

sdf split takes a large branch and decomposes it into a stack of focused, reviewable PRs. Claude analyzes your diff, identifies semantic themes, and creates each layer in dependency order — with hunk-level precision when the same file spans multiple concerns. The original branch is never touched.

Read the SDF split announcement →
⟳

Cascade rebase

sdf sync detects merged PRs and rebases every downstream branch in order, then force-pushes with --force-with-lease.

✦

AI-powered PR content

Claude generates PR titles and descriptions from your diffs. During sync, it can resolve rebase conflicts semantically.

✇

Safe one-at-a-time merging

sdf merge squash-merges the head PR, retargets downstream PRs, then cascade-rebases the rest of the stack.

⎇

Multiple stacks

Manage any number of independent stacks per repo. Each with its own base branch, nodes, and PR metadata.

◈

GitHub-native

Works entirely through gh CLI and git. No servers, no external services, no auth tokens beyond what you already have.

⬡

Stack reconciliation

sdf fetch discovers existing PR stacks from GitHub and reconciles them with local state. Join a stack on any machine.

Two ways to stack

Build a stack branch by branch, or split an existing branch into one automatically. Either way, SDF handles the rebasing when anything upstream changes.

1

Create a stack

Create a named stack and its first branch in one command. SDF tracks the topology in .sdf/ locally. Add more branches with sdf branch, then open PRs with sdf pr.

terminal
$ sdf new --branch db-schema users-feature
Initialized stack "users-feature" (base: main)
Created branch "users-feature/db-schema" (based on main)

Next steps:
  sdf pr               Create a pull request
  sdf branch <name>    Add another branch to the stack
  sdf status           View stack topology
2

Layer your branches

Add more branches to the stack. Each branch builds on the previous one. sdf pr creates the GitHub PR with the correct base branch and adds stack navigation links to every PR description — reviewers see the full stack at a glance.

terminal
$ sdf branch repository && sdf pr
Created branch "users-feature/repository" in stack "users-feature" (based on users-feature/db-schema)
https://github.com/.../pull/143

$ sdf status
  users-feature  (base: main)

   ● users-feature/db-schema    PR #142  open     in sync
 → ● users-feature/repository   PR #143  open     in sync
   ● users-feature/controller   PR #144  open     in sync
3

Sync when PRs merge

When an upstream PR merges, run sdf sync. SDF detects the merged PR, rebases every downstream branch in order, updates GitHub PR bases, and offers Claude-powered resolution if conflicts arise.

terminal
$ sdf sync
Syncing stack users-feature...
Fetching from origin...
  ✓ PR #142 (users-feature/db-schema) merged
  rebasing users-feature/repository onto main...
  ⚡ conflict in users-feature/repository — 1 file(s):
    internal/model/user.go
  invoking Claude for conflict resolution...
  ✓ conflict resolved by Claude
  ✓ users-feature/repository rebased and pushed
  ✓ users-feature/controller rebased and pushed
  ✓ 1 PR base(s) updated on GitHub

Sync complete. Stack updated.

Already have a big branch?

Split it into a stack

sdf split uses Claude to decompose an existing branch into focused, reviewable layers — without touching the original.

Point sdf split at any branch. Claude analyzes the diff, identifies semantic themes, and proposes a split plan. Review the plan, refine if needed, then execute — SDF creates the branches, verifies the split is lossless, pushes, and opens PRs.

See how SDF split works →
terminal
$ sdf split --from feature/big-change --stack my-feature
Analyzing feature/big-change...

Split plan for my-feature (base: main)
──────────────────────────────────────────
  Layer 1: schema (6 files, +142 -3)
  Layer 2: api (8 files, +310 -12)
  Layer 3: ui (9 files, +395 -28)

Executing split...
  ✓ Layer 1: my-feature/1-schema -- 6 files applied
  ✓ Layer 2: my-feature/2-api -- 8 files applied
  ✓ Layer 3: my-feature/3-ui -- 9 files applied
  ✓ Tree identity verified -- split is lossless

✓ Split complete -- 3 branches created in stack "my-feature"

PRs that document themselves

Stack navigation links are injected into every PR description automatically. Add --with-content and Claude generates titles and descriptions from your diffs.

Stack navigation in every PR

sdf pr and sdf sync inject a navigation section into every PR description. Reviewers see the full stack at a glance and can jump between related PRs. Links update automatically as PRs merge.

PR description #143

Add the UserRepository with CRUD operations and pgx integration.


Stack: users-feature

  1. add users table migration #142
  2. add user repository #143  ◀ this PR
  3. add user controller endpoints #144

AI-generated titles and descriptions

sdf sync --with-content uses Claude to generate PR titles and descriptions from your diffs. Titles are kept concise, descriptions explain the what and why. Only PRs with meaningful changes get updated — unchanged content is left alone.

terminal
$ sdf sync --with-content
Syncing stack users-feature...
  ...
  ✓ PR #143 title updated
  ✓ PR #143 description updated
  ✓ PR #144 title unchanged
  ✓ PR #144 description unchanged

Updated 1 PR(s).

Up and running in seconds

Requires git. GitHub CLI (gh) for PR operations. Claude CLI for AI features (optional).

Homebrew

macOS and Linux

brew install pavelpascari/tap/sdf

Go install

Go 1.24+ required

go install github.com/pavelpascari/sdf@latest

Binary download

All platforms

github.com/pavelpascari/sdf/releases

After installing

Set up your environment

Shell completions

Tab-complete commands, flags, branch names, and stack names. sdf completion install auto-detects your shell and writes the completion script to the right location.

terminal
$ sdf completion install
✓ Zsh completions installed to ~/.zsh/completions/_sdf
✓ Updated ~/.zshrc with fpath entry
  Restart your shell to activate.

Claude Code integration

One command teaches Claude how to use SDF — it creates a skill file so Claude remembers commands, workflows, and conventions across sessions.

terminal
$ sdf ai intro
→ Setting up SDF skill for Claude Code...

  ✓ Skill created. Claude Code will load SDF knowledge in future sessions.
Full installation guide →

Stop rebasing by hand.

SDF is free and open source. Run sdf doctor to verify your setup and start stacking.