jj-vine
A tool for submitting stacked Pull/Merge Requests from Jujutsu bookmarks.
Currently supports the following code forges:
- GitLab
The canonical location for jj-vine is codeberg.org/abrenneke/jj-vine. GitHub is used as a mirror and CI only.
Table of Contents
Overview
As jj is so flexible, it can sometimes be tedious to manage pull requests for a jj repository. Additionally, many people like the "stacked pull request" workflow, where a tool can manage your stack of pull requests for you, including modifying the base branch, description, and other settings. jj-vine aims to smooth out the process of managing pull requests for a jj repository.
There are many tools these days that aim to solve this problem, most notably jj-spr and jj-stack. jj-vine has its own preferred workflow and design choices, and is not a direct replacement for these tools. jj-vine aims to support multiple code forges.
Major differences:
jj-vineis bookmark-based, rather than change-based. It currently expects you to create and push your bookmarks before submitting them. This means that you can have multiple changes in each pull request.jj-spraims to more be a full workflow rather than a lightweight tool.jj-vineis less opinionated.jj-vineis primarily based around thesubmit --trackedcommand. This submits all (your) tracked bookmarks at once. Other tools often require you to submit each bookmark individually. The idea is to simply "sync your current state to the code forge".
Main Features
- Stacked pull request creation - Automatically creates pull requests with correct base branches based on bookmark dependencies
- Stack visualization - Adds a navigable stack diagram to pull request descriptions with links to related pull requests
- Automatic repointing - Updates pull request base branches when stack structure changes
- Complex Branching - Pull requests can branch into other sibling pull requests
Planned Features
- Automatic rebasing - Once a pull request is merged, rebases the stack on top of the trunk
Installation
Cargo Binstall
The preferred way to install jj-vine is to use cargo-binstall:
# Will put the binary in $HOME/.cargo/bin
Pre-built Binaries
Pre-built binaries are available for Linux, macOS, and Windows (ARM64 and x86_64). You can download from the releases page.
Alias Setup
You can set up a jj alias to make it easier to use jj-vine. Add the following to your ~/.config/jj/config.toml (or run jj config edit --user):
[]
= ["util", "exec", "--", "jj-vine"]
Then you can use jj vine instead of jj-vine. You can of course use any alias name you would like (jj mr or jj pr work well!).
Quick Start
-
Run
jj vine initto set up your code forge configuration for your repository. This is stored in.jj/repo/config.toml. You may also move any configuration settings to the global config file~/.config/jj/config.toml. -
Push up some bookmarks (auto-generated bookmarks work great!)
# Make some changes # Make some changes -
Submit all tracked bookmarks at once:
This creates two pull requests:
feature-atargetingmainfeature-btargetingfeature-a
Commands
submit
Submit a bookmark and its dependencies as pull requests.
# Submit a single bookmark (and its dependencies)
# Submit all tracked bookmarks
# Preview without making changes
See all options with jj vine submit --help.
init
Interactive setup wizard to configure jj-vine for your repository.
Configuration
Configuration is stored in jj's config system under the jj-vine section. You can use jj config edit --repo to edit the configuration for a specific repository. You can also use jj config set --repo <key> <value> to set a configuration value for a specific repository:
Required Settings
| Setting | Default | Description |
|---|---|---|
gitlabHost |
- | GitLab instance URL (e.g., https://gitlab.example.com) |
gitlabProject |
- | Project ID (group/project or numeric ID) |
gitlabToken |
- | Personal Access Token with api scope |
Optional Settings
| Setting | Default | Description |
|---|---|---|
remoteName |
origin |
Git remote name |
defaultBranch |
main or master or trunk depending on your repository |
Default target branch |
deleteSourceBranch |
true |
Sets pull request setting to delete source branch when pull request is merged |
squashCommits |
false |
Sets pull request setting to squash commits when pull request is merged |
assignToSelf |
false |
Assign created pull requests to yourself automatically |
defaultReviewers |
[] |
List of usernames to automatically add as reviewers to pull requests |
enableStackVisualization |
true |
Adds a stack diagram to pull request descriptions |
caBundle |
- | Path to CA certificate bundle. Use if you have a self-hosted code forge with a custom certificate |
tlsAcceptNonCompliantCerts |
false |
Accept non-strictly compliant TLS certificates. Use if you have a self-hosted code forge with a custom certificate and you know what you are doing |
Stack Visualization
When enabled, jj-vine adds a stack diagram to pull request descriptions:
This MR is part of a stack of 3 MRs:
1. 2.3.
If a pull request has multiple children, it will be listed multiple times in the stack diagram:
This MR is part of 3 stacks:
Stack 1 (2 MRs):
1. 2.
Stack 2 (2 MRs):
1. 2.
Stack 3 (2 MRs):
1. 2.
User content added before or after these markers is preserved on re-submission.
You may disable the stack visualization by setting jj-vine.enableStackVisualization to false in your configuration. If disabled, pull request descriptions will not be touched.
Credits
FAQs
Is this vibe-coded slop?
Don't worry, I berated Claude with profanity until things looked good.
Ok, but really?
This started as a test to see if Claude Code was an effective tool. Conclusion: meh. It made so many mistakes and bad decisions and I had to babysit it the entire time. A lot of code is AI-written, but I've done plenty of refactoring and cleanup myself. There are a decent amount of tests verifying the behavior. Lots of profanity really was involved.
Why a new project?
Well primarily, existing tools did not support GitLab. jj-spr was too heavy-handed. jj-stack was in TypeScript (nothing against it, but seems sane for a jj tool to also be built in Rust). My current jj workflow was also just different enough that those existing tools did not fit my needs.
Contributing
All contributions extremely welcome! Please feel free to open an issue or pull request. See CONTRIBUTING.djot for more details.