jj-ryu
Stacked PRs for Jujutsu. Push bookmark stacks to GitHub and GitLab as chained pull requests.
What it does
[feat-c]
@ mzpwwxkq a1b2c3d4 Add logout --> PR #3: feat-c -> feat-b
|
[feat-b]
o yskvutnz e5f6a7b8 Add sessions --> PR #2: feat-b -> feat-a
|
[feat-a]
o kpqvunts 9d8c7b6a Add auth --> PR #1: feat-a -> main
|
trunk()
Each bookmark becomes a PR targeting the previous bookmark (or trunk). When you update your stack, ryu updates the PRs.
Install
# npm (prebuilt binaries)
# cargo
Binary name is ryu.
Quick start
# View your current stack
# Track bookmarks for submission
# Submit tracked bookmarks as PRs
# Sync stack with remote
Authentication
GitHub
Uses (in order):
gh auth token(GitHub CLI)GITHUB_TOKENenv varGH_TOKENenv var
For GitHub Enterprise: export GH_HOST=github.mycompany.com
GitLab
Uses (in order):
glab auth token(GitLab CLI)GITLAB_TOKENenv varGL_TOKENenv var
For self-hosted: export GITLAB_HOST=gitlab.mycompany.com
Test authentication
Usage
Viewing your stack
Running ryu with no arguments shows the current stack (bookmarks between trunk and working copy):
$ ryu
Stack: feat-c
[feat-c]
@ yskvutnz e5f6a7b8 Add logout endpoint
|
[feat-b] ^
o mzwwxrlq a1b2c3d4 Add session management
|
[feat-a] *
o kpqvunts 7d3a1b2c Add user authentication
|
trunk()
3 bookmarks
Legend: * = synced, ^ = needs push, @ = working copy
Tracking bookmarks
Before submitting, bookmarks must be tracked. This gives you control over which bookmarks become PRs:
# Interactive selection (opens multi-select picker)
# Track specific bookmarks
# Track all bookmarks in trunk()..@
# Untrack a bookmark
Tracking state is stored in .jj/ryu/tracking.json per workspace.
Submitting
This pushes all tracked bookmarks in the current stack, creates PRs for any without one, updates PR base branches, and adds stack navigation comments. Untracked bookmarks are skipped with a warning.
Each PR gets a comment showing the full stack:
* #13
* **#12 👈**
* #11
---
This stack of pull requests is managed by jj-ryu.
Syncing
This fetches from remote and syncs the current stack.
Workflow example
# Start a feature
# Work on it
# Stack another change on top
# View the stack
# Track bookmarks for submission
# Submit both as PRs (feat-session -> feat-auth -> main)
# Make changes, then update PRs
# After feat-auth merges, rebase and re-submit
Advanced options
Preview and confirmation
Controlling submission scope
# Submit only up to a specific bookmark (excludes descendants)
# Submit only one bookmark (parent must already have a PR)
# Include all descendants in submission
# Only update existing PRs, don't create new ones
# Interactively select which bookmarks to submit
Draft PRs
# Create new PRs as drafts
# Publish draft PRs (mark as ready for review)
CLI reference
ryu [OPTIONS] [COMMAND]
Commands:
submit Submit tracked bookmarks as PRs
track Track bookmarks for submission
untrack Stop tracking bookmarks
sync Sync all stacks with remote
auth Authentication management
Options:
-p, --path <PATH> Path to jj repository
-h, --help Print help
-V, --version Print version
submit
ryu submit [OPTIONS]
Options:
--dry-run Preview without making changes
-c, --confirm Preview and prompt for confirmation
--upto <BOOKMARK> Submit only up to this bookmark
--only <BOOKMARK> Submit only this bookmark (parent must have PR)
--update-only Only update existing PRs
-s, --stack Include all descendants in submission
--draft Create new PRs as drafts
--publish Publish draft PRs
-i, --select Interactively select bookmarks
--remote <REMOTE> Git remote (default: origin)
track
ryu track [BOOKMARKS]... [OPTIONS]
Options:
-a, --all Track all bookmarks in trunk()..@
-f, --force Re-track already-tracked bookmarks
--remote <REMOTE> Associate with specific remote
untrack
ryu untrack <BOOKMARKS>...
Options:
-a, --all Untrack all bookmarks
sync
ryu sync [OPTIONS]
Options:
--dry-run Preview without making changes
-c, --confirm Preview and prompt for confirmation
--stack <BOOKMARK> Only sync this stack
--remote <REMOTE> Git remote (default: origin)
auth
ryu auth github test # Test GitHub auth
ryu auth github setup # Show setup instructions
ryu auth gitlab test # Test GitLab auth
ryu auth gitlab setup # Show setup instructions
Coming from Graphite?
Ryu's CLI is inspired by Graphite. Here's how commands map:
| Graphite | Ryu |
|---|---|
gt track |
ryu track |
gt submit |
ryu submit |
gt submit --stack |
ryu submit --stack |
gt submit --only |
ryu submit --only <bookmark> |
gt submit --draft |
ryu submit --draft |
gt submit --publish |
ryu submit --publish |
gt submit --confirm |
ryu submit --confirm |
gt sync |
ryu sync |
gt branch create |
jj bookmark create |
gt restack |
jj rebase |
Key differences:
- Ryu requires explicit tracking before submit (
ryu track) - Stack management uses jj commands (
jj bookmark,jj rebase), not ryu ryu sync --stack <bookmark>syncs a single stack (Graphite syncs all)
License
MIT