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 bookmark stacks
# Submit a stack as PRs
# Sync all stacks 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 stacks
Running ryu with no arguments shows your bookmark stacks:
$ ryu
Bookmark Stacks
===============
Stack #1: 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()
1 stack, 3 bookmarks
Legend: * = synced, ^ = needs push, @ = working copy
Submitting
This pushes all bookmarks in the stack, creates PRs for any without one, updates PR base branches, and adds stack navigation comments.
Each PR gets a comment showing the full stack:
* #13
* **#12 👈**
* #11
---
This stack of pull requests is managed by jj-ryu.
Syncing
# Sync all stacks
# Sync a specific stack only
Workflow example
# Start a feature
# Work on it
# Stack another change on top
# View the stack
# 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 a bookmark stack as PRs
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 <BOOKMARK> [OPTIONS]
Options:
--dry-run Preview without making changes
-c, --confirm Preview and prompt for confirmation
--upto <BOOKMARK> Submit only up to this bookmark
--only 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)
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 submit |
ryu submit <bookmark> |
gt submit --stack |
ryu submit <bookmark> --stack |
gt submit --only |
ryu submit <bookmark> --only |
gt submit --draft |
ryu submit <bookmark> --draft |
gt submit --publish |
ryu submit <bookmark> --publish |
gt submit --confirm |
ryu submit <bookmark> --confirm |
gt sync |
ryu sync |
gt branch create |
jj bookmark create |
gt restack |
jj rebase |
Key differences:
- Ryu requires an explicit bookmark argument (jj doesn't track "current branch")
- Stack management uses jj commands (
jj bookmark,jj rebase), not ryu ryu sync --stack <bookmark>syncs a single stack (Graphite syncs all)
License
MIT