DubStack
Guides

Migrating from Graphite

Map Graphite (`gt`) commands to DubStack equivalents and migrate an in-flight stack in under 30 minutes.

If you have gt muscle memory, this guide is the fast path to DubStack. The mental model is the same: branches stacked on branches, one PR per branch, automatic restack on rebase.

Command Mapping

GraphiteDubStackNotes
gt createdub createSame flags: -a, -m, --ai
gt modify / gt mdub modify / dub mAmend current branch and restack descendants
gt submit / gt ssdub submit / dub ss--stack, --upstack, --downstack, --branch
gt syncdub sync--all syncs every tracked stack
gt checkout / gt codub checkout / dub coInteractive picker with no argument
gt log / gt lsdub log / dub ls--stack, --all, --json
gt up / gt downdub up / dub downIdentical
gt top / gt bottomdub top / dub bottomIdentical
gt infodub info--json machine-readable
gt prdub prOpens the PR for the current branch
gt restackdub restackAutomatic when a parent changes
gt continuedub continueAdd --ai to resolve conflicts via LLM
gt abortdub abortRolls back restack/rebase
gt track --parentdub track --parentAdopt an untracked branch
gt untrackdub untrackKeep the branch, drop DubStack metadata
gt deletedub delete--upstack, --downstack, --force
gt parent / gt childrendub parent / dub children--json outputs the relation
gt trunkdub trunk / dub trunk add / dub trunk set-defaultMulti-trunk supported
gt undodub undo20-entry ring buffer, supports dub redo
gt absorbdub absorb--ai for ambiguous fixups
gt folddub foldDefaults to keeping commits; --squash to collapse
gt move --before/--afterdub move --before/--afterIdentical semantics
gt splitdub splitInteractive or AI-assisted commit split

Conceptual Differences

  • Local-first. All state lives in .git/dubstack/ and never leaves your machine. There is no DubStack account, no remote server, and no synchronization daemon. The downside is that team coordination happens through GitHub PRs alone.
  • Stack metadata in git refs. DubStack mirrors stack state into refs/dubstack/* so a wiped checkout can rebuild from dub init --restore-from-refs. Graphite stores the equivalent in .graphite_cache_persist.
  • First-class AI. dub create --ai, dub submit --ai, dub flow, and dub absorb --ai all use a provider you configure with dub config ai-provider. Set keys with dub config ai-model --provider anthropic <model>.
  • Safer merges. dub merge-next (alias dub land) refuses to merge a PR whose ancestors are not yet merged, and retargets every dependent PR atomically before deleting the local branch.
  • Multi-trunk. A single repository can have several trunks (e.g. main plus release/24.x). Configure with dub trunk add and dub trunk set-default.
  • MCP server. dub mcp exposes the local stack to AI coding agents via the Model Context Protocol, gated by dub config mcp-mode.

Common Pitfalls

  • gt submit --stack defaulted to the whole tree; dub submit defaults to downstack. Pass --stack explicitly when migrating CI scripts that assumed Graphite's old default.
  • gt sync --no-restack does not exist in DubStack. Use dub sync and then dub restack --continue if you wanted to defer restack.
  • .graphite_user_config is not read. Re-configure with dub config ai-provider, dub config reviewers, and friends.
  • gt downstack edit has no direct equivalent. Use dub reorder for interactive reordering, or dub move --before/--after for single-branch moves.

30-Minute Migration Script

The following walkthrough migrates an active Graphite stack in place without re-creating any branches or losing in-flight PRs.

# 1. Install DubStack (assumes pnpm/npm available)
npm install -g dubstack

# 2. From the repo root, initialize DubStack alongside Graphite
cd path/to/repo
dub init

# 3. Adopt every Graphite-tracked branch into DubStack. DubStack walks the
#    git ancestry to infer parent links — this is non-destructive.
git switch main
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads/); do
  if [ "$branch" != "main" ]; then
    git switch "$branch"
    dub track --no-interactive || true
  fi
done

# 4. Verify the stack matches what Graphite showed
dub log --all

# 5. Optional: enable AI features. Pick one provider.
dub config ai-assistant on
dub config ai-provider anthropic
dub config ai-model --provider anthropic claude-sonnet-4-7

# 6. Optional: pre-fetch your default reviewers so `dub submit` requests them
dub config reviewers alice,@org/backend

# 7. Confirm restack works on the active stack
dub restack

# 8. Resync PR descriptions with the new metadata layout
dub submit --downstack --no-ai

# 9. (When you are confident) remove Graphite
npm uninstall -g @withgraphite/graphite-cli
rm -rf .graphite_cache_persist .graphite_repo_config .graphite_user_config

# 10. Add an alias so muscle memory survives:
#     alias gt=dub      # zsh/bash

If anything looks off after step 4, run dub doctor for a diagnostic report. The state is recoverable via dub init --restore-from-refs.

See Also

On this page