| name | jj |
| description | Jujutsu (jj) — Git-compatible distributed VCS with undo and better branching. Use when: (1) managing code changes and commits, (2) creating or switching worktrees/branches (bookmarks), (3) rebasing or reorganizing commits, (4) reviewing git history, (5) any jj command appears in prompts, (6) user mentions jujutsu, bookmarks, or worktrees. Make sure to use this skill whenever the user mentions version control, branches, commits, git operations, or working with code changes — even if they don't explicitly say 'jj'. |
jj — Jujutsu Version Control
jj is a Git-compatible, Git-backed distributed VCS with first-class undo, better branching (bookmarks), and intelligent commit stacking. It stores history in the .jj/ directory and can work with existing Git repos.
When to Use
- Managing commits and changes (create, modify, split, squash)
- Working with branches (called "bookmarks" in jj)
- Rebasing and reorganizing commit history
- Reviewing repository state and history
- Creating worktrees for parallel development
- Any Git-like operation where jj's undo capability is valuable
Key Differences from Git
| Git Concept | jj Equivalent | Notes |
|---|
| Branch | Bookmark | jj bookmark |
git commit | jj describe -m + jj new | Or just jj commit -m |
git branch -d | jj bookmark delete | Deletions sync to remote on push |
| Worktree | Workspace | jj workspace |
| Stash | Commits are undoable | No stash needed |
Quick Reference
| Command | Purpose |
|---|
jj status | Show working copy state |
jj log | Show commit history |
jj new | Create new commit |
jj commit | Describe and commit (shorthand) |
jj bookmark | Manage bookmarks (branches) |
jj rebase | Move commits |
jj squash | Combine commits |
jj split | Split commits |
jj git push | Push to remote |
Essential Commands
Repository State
jj status
jj st
jj log
jj log -n 10
jj log --reversed
jj log -G
jj show @
jj show main
jj diff -r @-
jj diff -r main
jj diff --summary
Creating and Editing Commits
jj new
jj new main
jj commit -m "Add feature X"
jj ci -m "Fix bug Y"
jj describe -m "New description"
jj desc -m "Updated description"
jj diff
Bookmarks (Branches)
jj bookmark list
jj b list
jj bookmark set feature-x
jj b s my-feature
jj bookmark set feature-x -r @-
jj bookmark rename old-name new-name
jj b r old-name new-name
jj bookmark delete feature-x
jj b d feature-x
jj bookmark move feature-x -r main
jj bookmark track origin/main
jj b t origin/main
Navigating History
jj edit main
jj edit feature-x
jj prev
jj next
jj abandon
jj undo
jj redo
Rewriting History
jj rebase -s @ -o main
jj rebase -b feature-x -o main
jj rebase -r abc123 -o main
jj rebase -s mycommit -A main
jj rebase -s mycommit -B main
jj squash
jj squash -r feature-x
jj squash --from mycommit --into main
jj split
jj split file1 file2
jj duplicate mycommit
Absorb Changes
jj absorb
jj absorb --from @
jj absorb file1 file2
jj absorb -t main
Git Interop
jj git clone https://github.com/user/repo
jj git init
jj git export
jj git import
jj git push
jj git push --branch feature-x
jj git push --all
jj git fetch
jj git remote add origin https://github.com/user/repo
jj git remote list
Workspaces (Like Git Worktrees)
jj workspace list
jj workspace add ../workspace-name
jj workspace add ../backend -r main
jj workspace update-stale
jj workspace rename new-name
jj workspace forget workspace-name
Advanced History
jj evolog mycommit
jj parallelize mycommit
jj resolve
jj restore -r main -- file.txt
jj revert mycommit
Common Workflows
Feature Development
jj edit main
jj new
jj describe -m "Implement feature X"
jj describe -m "Add tests for feature X"
jj log
jj git push --branch my-feature
Rebase onto Updated Main
jj git fetch
jj rebase -b @ -o origin/main
jj log
Fix Bug in Middle of Stack
jj edit mycommit
jj describe -m "Fix bug in feature"
jj absorb
jj squash -r mycommit
Undo Operations
jj undo
jj redo
jj op log
jj op log -n 20
jj --at-op abc123 status
Revision (Revset) Syntax
@
@ - 1
@ - 2
main
origin/main
-:
@+
:@
main..@
::main
jj log -r 'description(grep: fix)'
jj log -r 'file(path_pattern: src/**/*.ts)'
Template Formatting
jj log -T 'commit_id.short() ++ " " ++ description.first_line() ++ "\n"'
jj log -T 'graph + " " ++ description.first_line()'
jj log -T 'commit_id.short() ++ " " ++ author.username() ++ " " ++ timestamp.format("%Y-%m-%d") ++ "\n " ++ description'
Global Options
-R, --repository <path>
--ignore-working-copy
--ignore-immutable
--at-operation <id>
--debug
--color <when>
--quiet
--no-pager
Tips
@ always points to working copy — safe to reference
- Commits are immutable by default — use
jj rebase or jj undo to modify
- Descriptions can be changed — no need for perfect commit messages upfront
- Pushing syncs deletions —
jj bookmark delete marks deletion for sync
- Workspaces > worktrees — jj's workspace support is more flexible than Git worktrees
- Full undo —
jj undo can undo ANY operation, not just commits