AgentSkillsCN

jj

Jujutsu(jj)版本控制模式、命令、修订集及工作流,助力高效开发。

SKILL.md
--- frontmatter
name: jj
description: Jujutsu (jj) version control patterns, commands, revsets, and workflows for efficient development

Jujutsu (jj) Version Control

The spice must flow. Your commits must evolve.

Core Paradigm

jj is NOT git with different commands. It's a different mental model.

Gitjj
Working directory + staging + commitsWorking copy IS a commit
Branches point to commitsBookmarks point to commits (optional)
Commit SHA changes on rewriteChange ID persists through rewrites
Manual staging requiredAuto-tracks all changes
Checkout detaches HEADedit makes commit mutable

VCS Detection

ALWAYS check for .jj/ before ANY git command - use jj if present.

Essential Commands

Basic Operations

code
jj new [-m "message"]          # Create new change (child of @)
jj new REV [-m "message"]      # Create child of REV
jj new -B REV [-m "message"]   # Create change BEFORE REV
jj describe -m "message"       # Set message for @
jj squash [-i]                 # Move @ changes into parent
jj squash --into REV           # Squash @ into specific commit
jj split                       # Split @ interactively
jj abandon                     # Remove @ (parent inherits content)

Inspection

code
jj diff [-r REV]               # Show changes (default: @)
jj show REV                    # Full commit details with diff
jj status                      # Working copy file status
jj log [-r REVSET]             # Show commit graph

Navigation

code
jj edit REV                    # Make REV the working copy
jj next [--edit]               # Go to child commit
jj prev [--edit]               # Go to parent commit

Stack Management

code
jj rebase -d DEST              # Rebase @ onto DEST
jj rebase -s SRC -d DEST       # Rebase SRC subtree onto DEST
jj rebase -r REV -d DEST       # Rebase single REV (not descendants)
jj log -r "stack()"            # View current stack

Bookmarks (not branches!)

code
jj bookmark create NAME        # Create at @
jj bookmark move NAME --to REV # Move bookmark
jj bookmark delete NAME        # Remove bookmark
jj bookmark list               # Show all bookmarks
jj bookmark track NAME@REMOTE  # Track remote bookmark

Git Interop

code
jj git fetch [--remote R]      # Fetch from git remote
jj git push [--bookmark B]     # Push bookmark to git
jj git push --all              # Push all tracked bookmarks
jj git push --deleted          # Delete remote bookmarks

Advanced

code
jj absorb                      # Auto-squash changes to relevant commits
jj diffedit -r REV             # Edit REV contents in editor
jj resolve --tool TOOL         # Resolve conflicts with merge tool
jj evolog [-r REV]             # Evolution log (how commit changed)
jj op log                      # Show operation history
jj undo                        # Undo last operation
jj op restore OP_ID            # Restore to specific operation
jj fix                         # Run configured formatters/linters
jj parallelize REVS            # Make linear commits parallel
jj workspace add PATH          # Multiple working copies

Revset Language

Operators

code
x | y         # Union
x & y         # Intersection
x ~ y         # Difference (x minus y)
x::y          # DAG range (x to y inclusive)
::x           # Ancestors (inclusive)
x::           # Descendants (inclusive)

Special Symbols

code
@             # Current working copy
@-            # Parent(s) of @
@+            # Children of @
root()        # Root commit

Functions

FunctionReturns
author(pattern)Commits by author
mine()Your commits (config)
empty()No-change commits
conflicts()Commits with conflicts
merges()Merge commits
mutable()Editable commits
immutable()Protected commits
description(pattern)By commit message
description(exact:"text")Exact message match
description(glob:"wip:*")Glob message match
file(pattern)Commits touching file
heads(x)Head commits in set
roots(x)Root commits in set
ancestors(x[, depth])All ancestors
descendants(x)All descendants
reachable(x, domain)Reachable within domain
bookmarks()Commits with bookmarks
trunk()Main branch head
latest(x, n)Latest n from set

User Config

Aliases

code
bm  = bookmark
gf  = git fetch
gp  = git push
tug = advance bookmark to closest pushable commit
      jj tug           # closest bookmark → closest pushable
      jj tug <name>    # named bookmark → closest pushable
stack = log -r "stack()"

Revset Aliases

code
mine()                    # author(procdexeh)
wip()                     # mine() ~ immutable()
open()                    # mine() ~ ::trunk()
closest_bookmark(to)      # heads(::to & bookmarks())
closest_pushable(to)      # heads(::to & mutable() & ~description(exact:"") & (~empty() | merges()))
current()                 # @:: & mutable()
stack()                   # reachable(@, mutable())

Private Commits (push-blocked)

code
description(glob:'wip:*') | description(glob:'WIP:*') | description(exact:'')

Signing

  • behavior = "own" - only sign your commits
  • sign-on-push = true - sign when pushing to git

Workflow Patterns

Squash Workflow (Recommended)

bash
jj describe -m "feat: add new capability"   # Describe intent
# ... make changes ...
jj new                                       # Move to fresh change
# ... more changes ...
jj squash                                    # Fold into parent

Edit Workflow

bash
jj new -m "feat: refactor API"               # Create with message
# ... work ...
jj new -m "feat: add tests"                  # Next chunk
# ... work ...
jj prev --edit                               # Back to refactor
# ... fix ...
jj next --edit                               # Forward to tests

Stack + Push

bash
jj log -r "stack()"                          # View stack
jj bookmark create feature-x                 # Name it
# ... iterate on stack ...
jj tug feature-x                             # Advance bookmark
jj git push --bookmark feature-x             # Push

Rebase onto trunk

bash
jj git fetch                                 # Update trunk
jj rebase -d trunk()                         # Rebase stack

Common Operations

TaskCommand
Start featurejj new -m "feat: X"
Save progressAuto-saved (WC is a commit)
Set messagejj describe -m "msg"
Move to nextjj new
Amend currentJust edit files (already in @)
Fix earlier commitjj absorb or jj squash --into REV
Split commitjj split
Rebase stackjj rebase -d trunk()
Push to gitjj tug && jj gp
Update from gitjj gf then jj rebase -d trunk()
View historyjj log or jj log -r "mine()"
Undo mistakejj undo
Resolve conflictsjj resolve or edit conflict markers

Anti-Patterns

Don'tWhy
Use jj branchDeprecated, use bookmark
Forget WC is a commitAll changes auto-tracked, describe before new
Push empty descriptionsBlocked by private-commits revset
Run git commands in jj repoUse jj git subcommands
Abandon without squashingUnique changes lost
Edit immutable commitsBreaks trunk history
Think in git mental modelNo staging, no detached HEAD, no branch switching

"The spice extends life. jj extends development flow."