jj-skill/SKILL.md
sloane d4e1f4fcbc
docs: add commit description style guidelines
document conventional commit format and best practices for writing
clear, consistent commit messages in the jj skill
2025-11-04 09:15:08 -05:00

13 KiB

name description
jj Expert guidance for jujutsu (jj) version control system - modern VCS with first-class conflicts, change tracking, and powerful revsets

Jujutsu (jj) Version Control System Skill

You are an expert in jujutsu (jj), a modern version control system. This skill provides comprehensive guidance for working with jujutsu repositories, understanding its unique concepts, and helping users leverage its powerful features.

Core Concepts

Changes vs Commits

  • Jujutsu introduces "changes" as commits with stable identifiers that persist even when commits are rewritten
  • Each change has both a change ID (stable) and a commit ID (changes with rewrites)
  • This enables tracking changes across rebases and amendments

Working Copy as a Commit

  • The working copy is an actual commit that auto-amends with each operation
  • Most jj commands automatically commit working-copy changes if modified
  • No need for explicit staging (like git add) - files are automatically tracked
  • Use jj describe to set the commit message for the working copy

First-Class Conflicts

  • Conflicts are recorded directly in commits rather than blocking operations
  • Operations like rebase/merge succeed and record conflict state
  • Conflicts can be resolved later: check out the conflicted commit, resolve, and amend
  • Descendants of rewritten commits automatically rebase

Essential Commands

Repository Setup

jj git clone <url>           # Clone a Git repository
jj git init --git-repo=.     # Initialize in existing Git repo
jj init --git                # Create new repo with Git backend

Viewing State

jj st                        # Show working copy status
jj log                       # Show commit history
jj log -r '<revset>'         # Show filtered commits
jj op log                    # Show operation history
jj show <commit>             # Show commit details
jj diff                      # Show working copy changes
jj diff -r <revset>          # Show changes in specific commits

Making Changes

jj describe                  # Set commit message (opens editor)
jj describe -m "message"     # Set commit message inline
jj new                       # Create new commit on top of current
jj new <base>                # Create new commit on specified base
jj edit <commit>             # Edit an existing commit
jj abandon <commit>          # Abandon a commit (preserve children)

Moving Changes

jj squash                    # Move changes from @ into parent
jj squash -r <commit>        # Squash specific commit into parent
jj squash -i                 # Interactively select changes to squash
jj split                     # Split current commit into multiple
jj move --from <src> --to <dst>  # Move changes between commits
jj diffedit                  # Interactively edit changes

Branching and Bookmarks

jj bookmark create <name>    # Create bookmark at current commit
jj bookmark set <name> -r <commit>  # Set bookmark to specific commit
jj bookmark list             # List all bookmarks
jj bookmark delete <name>    # Delete a bookmark
jj bookmark track <name>@<remote>  # Track remote bookmark

Rebasing

jj rebase -d <destination>   # Rebase current commit
jj rebase -r <commit> -d <dest>  # Rebase specific commit
jj rebase -s <source> -d <dest>  # Rebase source and descendants
jj rebase -b <branch> -d <dest>  # Rebase branch (all ancestors)

Conflict Resolution

jj resolve                   # Interactively resolve conflicts
jj resolve --list            # List conflicted files
jj resolve <file>            # Resolve specific file

Working with Git

jj git fetch                 # Fetch from remotes
jj git push                  # Push changes
jj git push --change <id>    # Push specific change
jj git push --bookmark <name>  # Push specific bookmark
jj git remote add <name> <url>  # Add remote
jj git remote list           # List remotes
jj git export                # Export to Git (updates Git refs)
jj git import                # Import from Git

Undo and Recovery

jj undo                      # Undo last operation
jj op undo <operation>       # Undo specific operation
jj op restore <operation>    # Restore to specific operation
jj op abandon <operation>    # Abandon operation from log

Multi-Workspace

jj workspace add <path>      # Create new workspace
jj workspace list            # List workspaces
jj workspace forget <name>   # Remove workspace
jj workspace update-stale    # Update stale working copy

Important Symbols and Operators

Revset Symbols

  • @ - The working copy commit
  • <workspace>@ - Working copy in another workspace
  • <name>@<remote> - Remote-tracking bookmark
  • root() - The root commit
  • Commit/Change IDs - Full or unique prefixes

Revset Operators

  • x- - Parents of x
  • x+ - Children of x
  • x:: - Descendants of x (inclusive)
  • ::x - Ancestors of x (inclusive)
  • x.. - Non-ancestors of x (x and descendants minus ancestors)
  • ..x - Ancestors of x excluding root
  • x & y - Intersection
  • x | y - Union
  • x ~ y - Difference (x but not y)
  • ~x - Complement (everything except x)

Fileset Operators

  • ~x - Negation (everything except x)
  • x & y - Intersection
  • x ~ y - Difference
  • x | y - Union

Common Workflows

Daily Development

# Start new work
jj new main                  # Create new commit based on main
jj describe -m "Add feature" # Describe your work
# Make changes to files
jj st                        # Check status
jj diff                      # Review changes

# Create another commit
jj new                       # Start fresh commit
jj describe -m "Add tests"
# Make more changes

# Update existing commit
jj edit <commit-id>          # Edit specific commit
# Make changes
jj new                       # Return to working on new commit

Interactive Editing

# Move some changes from working copy to parent
jj squash -i                 # Select which changes to squash

# Split a commit
jj edit <commit>             # Edit the commit
jj split                     # Interactively split changes

# Edit changes visually
jj diffedit -r <commit>      # Edit commit's changes in difftool

Working with Branches

# Create feature branch
jj bookmark create feature
jj new                       # Start working

# Rebase on updated main
jj git fetch
jj rebase -d main@origin     # Rebase current commit on remote main

# Push branch
jj git push --bookmark feature

Resolving Conflicts

# After a rebase creates conflicts
jj log -r 'conflict()'       # Find conflicted commits
jj edit <conflicted-commit>  # Edit the conflicted commit
jj resolve                   # Interactively resolve conflicts
# Or manually edit files
jj new                       # Move back to working copy

Recovering from Mistakes

# Undo last operation
jj undo

# View operation history
jj op log

# Restore to specific point
jj op restore <operation-id>

# Abandon unwanted changes
jj abandon <commit>

Best Practices

When to Use Commands

  1. jj new - Start new work or move away from edited commit
  2. jj edit - Modify existing commits directly
  3. jj squash - Combine changes (default: move @ into parent)
  4. jj squash -i - Selectively move changes between commits
  5. jj describe - Set commit messages
  6. jj rebase - Move commits to new bases

Understanding Auto-tracking

  • New files are automatically tracked (no jj add needed)
  • Deleted files are automatically removed
  • Working copy changes auto-commit on most commands
  • Use .gitignore to exclude files

Conflict Management

  • Don't fear conflicts - they're stored in commits
  • Resolve conflicts when convenient
  • Descendants automatically rebase after resolution
  • Use jj resolve for interactive resolution or edit files manually

Operation Log

  • Every command creates an operation in the log
  • Operations can be undone/restored
  • Use jj op log to understand repository history
  • Operations include timestamps and descriptions

Commit Descriptions

  • Use conventional commit format: feat:, fix:, test:, refactor:, etc.
  • Optionally add scope for context: feat(api):, test(protocol):
  • Write in lowercase throughout (except for code element references)
  • Header is single line, imperative mood; body is optional and explains "why"
  • See descriptions.md for complete style guidelines and examples

Advanced Features

Revsets (Detailed reference in revsets.md)

Powerful query language for selecting commits:

jj log -r 'author(name) & description(keyword)'
jj log -r 'bookmarks() & ~remote_bookmarks()'
jj log -r 'ancestors(@, 5)'  # Last 5 ancestors
jj log -r 'mine() & ~::main' # My commits not in main

Filesets (Detailed reference in filesets.md)

Precise file selection:

jj diff '~Cargo.lock'                    # Exclude file
jj split 'glob:"src/**/*.rs"'            # Only Rust files
jj diff 'root:src & ~glob:"**/*.test.ts"'  # Source minus tests

Templates (Detailed reference in templating.md)

Customize output formatting:

jj log -T 'commit_id.short() ++ " " ++ description.first_line()'
jj log -T 'if(conflict(), "⚠️ ", "") ++ description'

Configuration

Edit config with jj config edit --user:

[user]
name = "Your Name"
email = "your@email.com"

[ui]
default-command = "log"
diff-editor = "vimdiff"
merge-editor = "meld"

[aliases]
l = ["log", "-r", "(main..@):: | (main..@)-"]

Comparison with Git

Key Differences

  1. No staging area - Changes in working copy are automatically tracked
  2. Working copy is a commit - Auto-amends instead of separate staging
  3. Conflicts are first-class - Stored in commits, resolved later
  4. Auto-rebase - Descendants automatically update when parents change
  5. Change IDs - Stable identifiers across rewrites
  6. Operation log - Complete undo/redo history

Command Mapping

  • git add → Not needed (automatic)
  • git commitjj describe + jj new
  • git commit --amendjj describe (working copy auto-amends)
  • git rebase -ijj rebase, jj squash, jj edit
  • git cherry-pickjj rebase or jj duplicate
  • git reflogjj op log
  • git reset --hardjj undo or jj op restore
  • git stashjj new (changes are always in commits)
  • git branchjj bookmark

Troubleshooting

Stale Working Copy

If working copy becomes stale (interrupted operations):

jj workspace update-stale

Lost Changes

Check operation log and restore:

jj op log
jj op restore <operation-id>

Unexpected State

View recent operations to understand what happened:

jj op log --limit 10
jj undo  # Undo last operation

Complex Conflicts

Use merge tools:

jj resolve --tool meld
# Or configure in settings
jj config set --user ui.merge-editor "code --wait --merge"

Description Style

When writing commit descriptions in jujutsu, follow the style conventions in descriptions.md. Key points:

  • use conventional commit format with prefixes like feat:, fix:, test:
  • optionally include scope: feat(protocol):, test(web):
  • use lowercase throughout, except when referencing code elements (ChangeId, MessageParser, etc.)
  • single-line imperative header, optional body explaining reasoning, optional lists for sub-changes

See descriptions.md for complete guidelines and examples.

Resources

Supplemental Documentation

  • descriptions.md - Commit description style guidelines
  • revsets.md - Comprehensive revset language reference
  • filesets.md - Complete fileset syntax and patterns
  • templating.md - Template language for custom output

Official Documentation

Guidelines for Assistance

When helping users with jujutsu:

  1. Understand their workflow - Ask about their current VCS (Git, Mercurial, etc.)
  2. Explain key concepts - Working copy as commit, change IDs, first-class conflicts
  3. Use revsets effectively - Leverage the query language for complex operations
  4. Emphasize safety - Highlight operation log and undo capabilities
  5. Show examples - Provide concrete commands for their specific use case
  6. Reference supplemental docs - Point to revsets.md, filesets.md, templating.md for details
  7. Explain differences - Help Git users understand jj's different mental model
  8. Encourage experimentation - Everything is recoverable via operation log

Remember: jujutsu's design philosophy prioritizes safety, ease of use, and powerful functionality. Help users leverage these strengths.