mit einem Klick
mit einem Klick
Execute a list of tasks as a stack of PRs using Graphite (`gt`). Each task becomes one branch, one commit, one PR. Use when the project uses stacked PRs via Graphite and you have multiple tasks to ship.
Expert guidance on Neovim configuration, plugin management, lazy.nvim, LSP setup, and editor workflow optimization
Walk a Graphite stack bottom-to-top, fixing PR review comments on each branch
Stacked PRs with Charcoal CLI (charcoal)
Distribute uncommitted changes across a Graphite stack using a backup branch
Generate feature documentation — PRDs, RFCs, ADRs, plans, technical docs, tasks, guides, testing docs, runbooks, and changelogs — individually or as a progressive pipeline covering a feature's full lifecycle
| name | graphite |
| description | Stacked PRs with Graphite CLI (gt) |
Manage development work as stacked pull requests using the Graphite CLI (gt).
Every task becomes a small, focused PR stacked on the previous one, enabling
fast review cycles and incremental merging.
| Term | Meaning |
|---|---|
| Trunk | Main branch (main/master) — base of all stacks |
| Stack | Chain of dependent branches, each building on the one below |
| Upstack | Branches above the current one (depend on current) |
| Downstack | Branches below the current one (current depends on) |
| Restack | Rebase all branches to maintain proper parent chain |
A "stack" is the linear chain of branches the current branch belongs to — NOT all open PRs in the repo. A repo can have multiple independent stacks.
# CORRECT — shows only branches in the current stack
gt log short
# WRONG — shows ALL open PRs across ALL stacks
gh pr list --author @me --state open
Always use gt log short to determine which branches are in your current stack.
Then cross-reference with gh pr list --head "branch-name" to get PR numbers
for specific branches.
See references/identify-stack-prs.md for detailed examples and common
mistakes.
gt vs gh Boundariesgt handles stack management (branches, rebasing, submitting). gh handles
GitHub API (comments, reviews, CI status). There is no gt command for
fetching PR review comments — use gh api for that.
See references/gt-vs-gh.md for a complete reference table.
# Ensure you're on trunk and up to date
gt sync
gt checkout main
# Create your first task branch
# Make changes with your editor, then:
gt create --all --message "feat(scope): description of first task"
# Push and create the PR
gt submit --ai
# You're already on the first task's branch
# Make more changes, then stack on top:
gt create --all --message "feat(scope): description of next task"
# Push the entire stack
gt submit --stack --ai
# Compact stack view
gt log short
# or
gt ls
# Open current PR in browser
gt pr
gt up # Move to child branch (one step up)
gt down # Move to parent branch (one step down)
gt top # Jump to top of stack
gt bottom # Jump to bottom of stack
gt checkout # Interactive branch picker
gt checkout NAME # Jump to specific branch
# Stage and amend the current branch's commit
gt modify --all
# Or create a new commit on the branch
gt modify --all --commit --message "address review feedback"
# Push updates (restacks upstack branches automatically)
gt submit --stack --ai
# Stage changes, then let Graphite figure out which commit they belong to
git add -A
gt absorb
# Navigate to where you want to insert below
gt checkout parent-branch
# Create new branch — it inserts between parent and former child
gt create --all --message "fix(scope): inserted fix"
# Restack to fix the chain
gt restack
gt submit --stack --ai
# Split current branch by commit, hunk, or file
gt split
# Merge current branch's changes into parent
gt fold
# Pull latest trunk, rebase all stacks, clean up merged branches
gt sync
Run gt sync frequently — it handles:
# Ensure parent chain integrity after manual git operations
gt restack
# If a restack or sync hits a conflict:
# 1. Resolve conflicts in your editor
# 2. Stage resolved files
git add .
gt continue
# Or abort the operation
gt abort
gt undo
After a PR in the middle of a stack is merged (e.g., via GitHub squash merge),
gt submit --stack --ai may fail with:
WARNING: PR for the following branch has already been merged but the merged
commits are not contained in the latest trunk branch main.
ERROR: Aborting non-interactive submit.
This happens because trunk has the squash-merged commit, but Graphite still sees the original branch commits and cannot reconcile them automatically.
Recovery steps:
# 1. Pull trunk and clean up what Graphite can auto-detect
gt sync
# 2. If the merged branch still blocks submit, check your stack
gt log short
# 3. Go to the first unmerged branch above the stuck one
gt checkout <first-unmerged-branch>
# 4. Reparent it directly onto main (skipping the merged branch)
gt track --parent main
# 5. Restack to rebase all upstack branches onto the new parent chain
gt restack
# 6. Now submit works again
gt submit --stack --ai --publish
Why this works: The merged branch's commits were squashed into a single
commit on trunk that does not match the original commits. Graphite cannot
automatically detect they are the same changes. By reparenting the first
unmerged child onto main, you tell Graphite to skip the stale branch and
rebase directly onto trunk, which already contains the merged work.
# Submit current branch only
gt submit --ai
# Submit entire stack (recommended)
gt submit --stack --ai
# Submit with reviewers
gt submit --stack --ai --reviewers alice,bob
# Update PR title/body interactively
gt submit --edit --ai
# Navigate to the top of what you want to merge
gt top
gt pr # Opens in browser — click Merge
# Or merge from CLI
gt merge
After merging:
gt sync # Cleans up merged branches, rebases remaining stack
| Command | Alias | Purpose |
|---|---|---|
gt init | Initialize Graphite in a repo | |
gt create -am "msg" | gt c | Create branch with all changes committed |
gt modify -a | gt m | Amend current commit, auto-restack upstack |
gt submit --ai | gt s | Push and create/update PR |
gt submit --stack --ai | Push and create/update all PRs in stack | |
gt sync | Pull trunk, rebase stacks, clean merged |
| Command | Alias | Purpose |
|---|---|---|
gt up [steps] | gt u | Move to child branch |
gt down [steps] | gt d | Move to parent branch |
gt top | gt t | Jump to top of stack |
gt bottom | gt b | Jump to bottom of stack |
gt checkout [branch] | gt co | Interactive branch picker |
gt log short | gt l | View stack tree |
| Command | Alias | Purpose |
|---|---|---|
gt restack | gt r | Fix parent chain integrity |
gt absorb | gt ab | Route staged changes to correct commits |
gt split | gt sp | Split branch by commit/hunk/file |
gt squash | gt sq | Squash all commits into one |
gt fold | Merge branch into parent | |
gt move | Rebase branch onto different parent | |
gt reorder | Reorder branches interactively | |
gt pop | Delete branch, keep working tree changes |
| Command | Alias | Purpose |
|---|---|---|
gt delete [name] | gt dl | Delete branch, restack children |
gt rename [name] | gt rn | Rename current branch |
gt track [branch] | gt tr | Start tracking branch with Graphite |
gt untrack [branch] | gt utr | Stop tracking branch |
gt freeze [branch] | Prevent local modifications | |
gt unfreeze [branch] | Re-enable modifications | |
gt get [branch] | Sync branches from remote |
| Command | Purpose |
|---|---|
gt pr [branch] | Open PR in browser |
gt merge | Merge PR stack via Graphite |
gt dash | Open Graphite dashboard |
| Command | Alias | Purpose |
|---|---|---|
gt continue | gt cont | Resume after conflict resolution |
gt abort | Cancel in-progress rebase | |
gt undo | Undo last Graphite operation |
When given a list of tasks to implement:
gt sync — start from a clean, up-to-date trunkgt create --all --message "type(scope): description" c.
gt submit --stack --aigt sync if trunk has advancedgt checkout branch, fix, gt modify -a,
gt submit --stack --aigt sync to clean upFollow conventional commits:
feat(scope): add new feature
fix(scope): fix the bug
refactor(scope): restructure without behavior change
test(scope): add or update tests
docs(scope): documentation only
chore(scope): maintenance tasks
Graphite uses temporary graphite-base/* branches during merge operations. In a
stack, each PR targets its parent branch, not main. Only the bottom PR in
a stack targets main directly.
CI impact: If your CI workflow triggers only on
pull_request: branches: [main], stacked PRs above the bottom won't trigger CI
because their base is a parent branch, not main.
Solutions:
gt submit --stack which manages bases correctlymain automatically — CI runs theregh pr edit --base main — this breaks Graphite's stack
tracking. If CI isn't running, the PR isn't the bottom of the stack yet. Merge
the PR below it first, then gt sync will update this PR's base to main.gt sync, the next PR becomes the new
bottom and targets main — CI will triggergt restack restacks the current branch AND all descendants (upstack
branches). You cannot restack only the current branch without touching
descendants — maintaining the chain is the whole point.
When downstream branches have conflicts:
gt restack pauses at the first conflictgit add <files>, gt continue — or gt abort to cancelgt sync cleans up merged branchesAfter a restack changes commit SHAs:
gt submit may show a "non-fast-forward" warning because the remote has old
SHAs — this is normal, gt submit force-pushes by designgt submit says "No-op", the remote already has the latest commitsgt submit --stack after restack to update all PRs in the stackWhen fixes need to land on different branches in the stack (e.g., a reviewer
comments on code introduced in a lower PR), navigate to each branch, make
targeted edits, and gt modify --all. Do NOT use
git checkout stash@{0} -- <file> — it brings the entire file from stash,
leaking changes from other branches.
See references/distribute-fixes.md for the full workflow.
In worktree environments, gt sync produces warnings about branches checked out
in other worktrees. These are benign — ignore them and focus on your current
stack with gt log short.
See references/worktree-tips.md for details.