Jujutsu (jj)
Dedicated Checkout Workflow
This checkout is yours alone. No other work happens here. The workflow is:
- Start fresh:
jj git fetchthenjj new main@origin - Do work: Create commits as needed
- Push PR: Create ONE bookmark on HEAD, push ALL commits (main..HEAD)
- Iterate: If PR needs updates, commit more, push same bookmark
- Done: PR merges via GitHub, return to step 1
CRITICAL Rules
- "All files" means ALL files - When told to commit, restore, or rebase "all files", include every modified file in the working copy. Never selectively exclude files. The working copy is the source of truth.
- ONE bookmark only - Never create multiple bookmarks
- Push ALL commits - Always push the entire stack from main to HEAD
- Never partial pushes - Don't push just one commit when there are more
- Bookmark on HEAD - The bookmark always points to the top of your stack
Starting Work
jj git fetch
jj new main@origin
This puts you on a fresh commit with main as parent. All your work builds from here.
Committing
When user says "commit", use jj commit -m "msg":
jj commit -m "Add feature X"
Commits stack automatically. After 3 commits you have: main → A → B → C (@)
Creating a PR
When ready to push:
# Create bookmark on current commit (HEAD of your stack)
jj bookmark create feature-name
# Track the bookmark (required before first push)
jj bookmark track feature-name@origin
# Push the bookmark (pushes ALL commits from main to HEAD)
jj git push --bookmark feature-name
Updating a PR
If PR needs changes:
# Make changes, commit
jj commit -m "Fix review feedback"
# Move bookmark to new HEAD
jj bookmark set feature-name
# Push updated bookmark
jj git push --bookmark feature-name
Rebasing a Remote Branch onto main
Remote commits are immutable — jj rebase will fail on them. To rebase a remote branch's changes onto main@origin, use jj restore:
jj new main@origin
jj restore --from <bookmark>@origin
This creates a new working copy on main and applies all the branch's changes on top. Never use jj rebase on remote commits.
Prohibited Operations
- Modifying
mainbookmark locally - Merging into main locally (PRs only)
- Force pushing to main
- Creating multiple bookmarks
- Pushing partial commit stacks
Squashing (Permission Required)
NEVER squash without explicit user permission.
jj edit <revision>
jj squash -m "Combined message"
After squashing, update and push bookmark:
jj bookmark set feature-name
jj git push --bookmark feature-name
Recovery
All operations are logged:
jj op log
jj op restore <operation-id>
Common Commands
| Task | Command |
|------|---------|
| Fetch remote | jj git fetch |
| Start fresh on main | jj new main@origin |
| Check status | jj status |
| View changes | jj diff |
| View log | jj log |
| Commit | jj commit -m "msg" |
| Create bookmark | jj bookmark create <name> |
| Move bookmark to HEAD | jj bookmark set <name> |
| Push bookmark | jj git push --bookmark <name> |
| Track new bookmark | jj bookmark track <name>@origin |
Key Concepts
- Working copy (
@): Always a commit being edited - Bookmarks: Named pointers to commits (like git branches)
- main@origin: The remote main branch
- Commit stack: Your commits from main to HEAD, all pushed together