jj-skill/SKILL.md
sloane d18742e067
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:16:24 -05:00

376 lines
12 KiB
Markdown

---
name: jj
description: 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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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
```bash
jj resolve # Interactively resolve conflicts
jj resolve --list # List conflicted files
jj resolve <file> # Resolve specific file
```
### Working with Git
```bash
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
```bash
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
```bash
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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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:
```bash
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:
```bash
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:
```bash
jj log -T 'commit_id.short() ++ " " ++ description.first_line()'
jj log -T 'if(conflict(), "⚠️ ", "") ++ description'
```
### Configuration
Edit config with `jj config edit --user`:
```toml
[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 commit``jj describe` + `jj new`
- `git commit --amend``jj describe` (working copy auto-amends)
- `git rebase -i``jj rebase`, `jj squash`, `jj edit`
- `git cherry-pick``jj rebase` or `jj duplicate`
- `git reflog``jj op log`
- `git reset --hard``jj undo` or `jj op restore`
- `git stash``jj new` (changes are always in commits)
- `git branch``jj bookmark`
## Troubleshooting
### Stale Working Copy
If working copy becomes stale (interrupted operations):
```bash
jj workspace update-stale
```
### Lost Changes
Check operation log and restore:
```bash
jj op log
jj op restore <operation-id>
```
### Unexpected State
View recent operations to understand what happened:
```bash
jj op log --limit 10
jj undo # Undo last operation
```
### Complex Conflicts
Use merge tools:
```bash
jj resolve --tool meld
# Or configure in settings
jj config set --user ui.merge-editor "code --wait --merge"
```
## 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
- Main docs: https://jj-vcs.github.io/jj/latest/
- Tutorial: https://jj-vcs.github.io/jj/latest/tutorial/
- GitHub: https://github.com/martinvonz/jj
## 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.