CtrlK
BlogDocsLog inGet started
Tessl Logo

pleaseai/graphite

Stacked PR workflow with the Graphite CLI (gt) — create stacks, submit, sync, restack, split/squash/fold, track existing branches, collaborate on shared stacks, configure repo/CI for Graphite, and operate the merge queue.

70

Quality

88%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/graphite/

name:
graphite
description:
Drive the Graphite CLI (`gt`) for stacked pull-request workflows. Use when the user works with stacked PRs, mentions Graphite, gt, "the stack", or wants to create/submit/sync/restack/split/squash/fold branches. Triggers on `gt` commands, "stack of PRs", "stacked diffs", "trunk-based", `.graphite_repo_config`, branches prefixed by a Graphite user (e.g. `lms--`, `pp--`).
tools:
Bash, Read, Grep, Glob, Edit
user-invocable:
No

Graphite CLI (gt) — Stacked PR Workflow

Invoke the CLI as gt (not graphite). A stack is a chain of branches where each builds on its parent and maps to one PR.

When the user is in a Graphite repo (.git/.graphite_repo_config present) or mentions stacked PRs / gt / Graphite, prefer gt over raw git for branch creation, rebasing, and pushes. Plain git still works for staging, diffing, logs, and inspection.

Core mental model

  • One commit per branch. Stack additional changes by creating new branches on top, not new commits on the same branch.
  • Trunk is main (or whatever gt init selected). Stacks are rooted on trunk.
  • gt knows the parent of every tracked branch. It uses that metadata to restack automatically when ancestors change.
  • Do not use raw git rebase to move tracked branches. It can wipe Graphite metadata. Use gt modify, gt restack, or gt move instead.

The golden path: create → submit

# Make changes, then:
gt create -am "feat: add activity feed API"   # stage all, commit, new branch
# More changes for the next layer:
gt create -am "feat: render feed in UI"       # creates branch on top of previous
gt submit --stack                              # push all branches, open PRs
  • gt create [name] creates a branch from the current HEAD with the staged changes already committed. With -a it stages all changes; with -m "..." it sets the commit message; combined -am "..." is the common form.
  • gt c is the alias for gt create.
  • gt submit pushes the current branch and downstack; gt submit --stack (alias gt ss) pushes every branch in the current stack and opens/updates PRs for each.

Viewing the stack

gt log         # full tree with branches, PRs, worktree paths
gt ls          # compact view (alias for `gt log short`)

The filled circle (◉) marks the current branch. Always run gt ls before any restack/move operation to confirm parent relationships.

Navigating the stack

GoalCommandAlias
Move up one branchgt upgt u
Move down one branchgt downgt d
Top of stackgt topgt t
Bottom of stackgt bottomgt b
Specific branch (interactive)gt checkoutgt co
Jump to trunkgt checkout --trunkgt co -t
Show parentgt parent
Show childrengt children

gt up and gt top prompt for disambiguation when a branch has multiple children.

Editing a mid-stack branch

gt co some_mid_branch       # check out the branch
# edit files
gt modify -a                # amend the existing commit; upstack restacks automatically
# OR add a new commit on this branch:
gt modify -cam "fix tests"
  • gt modify (alias gt m) amends the current branch's commit and automatically restacks every upstack descendant. No need to run gt restack manually after a clean modify.
  • Use -c / --commit to add a new commit instead of amending.
  • Use --into <branch> to amend staged changes into a downstack branch in one step.
  • For changes that should land in multiple downstack branches simultaneously, use gt absorb -a (Graphite picks the right branch per hunk).

When restack hits a conflict

# resolve conflicts in editor
gt add .                     # mark resolved (gt add wraps git add)
gt continue -a               # finish the restack
# or
gt abort                     # bail out safely

Syncing with the remote

gt sync

This single command:

  1. Pulls trunk from origin,
  2. Detects merged branches and prompts to delete them,
  3. Restacks the remaining branches onto the new trunk tip.

If a restack conflicts, gt sync exits with a list of branches to fix. Check each out and run gt restack, then resolve as above.

Prefer gt sync over git pull whenever the working repo has tracked Graphite branches — git pull won't restack the stack.

Submitting / updating PRs

gt submit               # current branch + downstack
gt submit --stack       # entire current stack (alias: gt ss)
gt submit --stack -u    # update PRs only, don't create new ones (gt ss -u)

gt submit interactively asks whether to open a draft PR and whether to edit the description. To skip prompts, pass -c / --confirm. To open the editor unconditionally, pass -e / --edit.

Manual restack

You only need this when:

  • gt sync reported conflicts on a branch, or
  • A parent advanced (squash-merge on GitHub) and children still point at the old SHA, or
  • After a git rebase you ran by hand on a tracked branch (avoid this).
gt restack              # restack current stack on top of current parents
gt restack -u           # only upstack from current branch
gt restack -d           # only downstack
gt restack -o           # only this branch (no children/parents)

Reorganizing the stack

OperationCommandNotes
Move current branch to a new parentgt move --onto <branch>Restacks dependents automatically
Interactive reordergt reorderOpens editor with branch list; rearrange lines
Insert a new branch mid-stackgt create --all --insert -m "..."Other branches restack onto it
Fold branch into its parentgt fold--keep keeps the child's name
Squash a multi-commit branch into onegt squashOpens editor for the new message; -m "..." to skip
Split a branchgt split --by-commit / --by-file "*.json" / --by-hunkThree modes
Delete a branch but keep the changesgt pop
Delete a branch entirelygt delete [-f]-c also closes the PR

When splitting a branch that already has a PR, keep the original branch name for one of the pieces — GitHub PR branch names are immutable, so any renamed piece becomes a new PR.

Tracking existing git branches

If a branch was created with raw git checkout -b, Graphite doesn't know its parent yet:

gt track                    # prompts to pick a parent (or the only candidate)
gt track <branch>           # track a specific branch
gt track --force            # auto-pick nearest ancestor as parent
gt untrack <branch>         # stop tracking

Run gt track from the tip of an external stack to track multiple branches at once (walks up until it hits an already-tracked branch).

Collaborating on someone else's stack

gt get <branch>             # fetch their stack locally
# branches arrive frozen by default — no accidental edits
gt unfreeze <branch>        # to extend their work
gt create -am "my addition" # stack your branch on top
gt submit                   # push and open your own PR(s)

gt freeze / gt unfreeze toggle the lock manually. gt info shows freeze status.

Worktrees

gt log displays a worktree path next to any branch checked out elsewhere. Rules of thumb:

  • gt sync, gt get, gt restack must be run from each worktree that owns branches in the stack.
  • To start a branch on top of a branch that's checked out in another worktree, use gt create --onto <branch> from the current worktree.
  • gt undo is per-worktree.

Multiple trunks

Repos that maintain release branches alongside main can register both as trunks:

gt trunk --add release-v10
gt trunk --all
gt sync --all              # sync every trunk and its stacks
gt log short --all         # show stacks across all trunks

Branches are auto-associated with whichever trunk they were created off of.

Recovery

  • gt undo reverses the most recent Graphite mutation (per worktree).
  • Conflicts during any restack-style operation: gt add .gt continue -a, or gt abort to back out.

Operating principles for Claude

  • Before any restack, move, fold, squash, or split, run gt ls and show the output so the user sees the current shape.
  • Never run git rebase, git reset --hard, or git push --force on a tracked branch without explicit confirmation — use the gt equivalent (gt modify, gt restack, gt move, gt submit --force).
  • After resolving a restack conflict, prefer gt continue over running git rebase --continue directly.
  • When the user asks for a "new branch on top of X," default to gt create -am "..." from X — don't construct branch names manually unless asked; gt derives them from the commit message.
  • For multi-commit work, ask whether to keep multiple commits (gt modify -c) or amend (gt modify) — the answer determines whether the next gt submit updates the same PR or needs gt squash first.
  • If .git/.graphite_repo_config is missing, treat the repo as un-initialized and propose gt init before any other gt command.

skills

graphite

README.md

tile.json