"LLM-specific guidance for using jujutsu. Complements commit skill with jujutsu-specific workflows: working copy model, commit commands, file tracking, non-interactive operations. Triggers: jj commands, jujutsu workflows, working copy questions, bookmark management."
Resources
1Install
npx skillscat add sebnow/configs/jujutsu Install via the SkillsCat registry.
Jujutsu
Overview
LLM-specific guidance for using jujutsu effectively.
Follow commit skill for VCS-agnostic principles
(atomic commits, message format, conventions).
This skill covers jujutsu-specific workflows and commands.
Understanding Working Copy (Critical)
The working copy is part of the current commit (@).
In jujutsu, uncommitted changes are not "staged" -
they ARE the current commit until you advance:
# Make edits to files
jj status
# Shows: Working copy changes:
# M file.go
# These changes are PART of commit @ right now
jj commit -m "message"
# Now @ is empty and those changes are in @-Critical implications:
- Any files you edit are immediately part of @ (the current commit)
- If @ already has a description, your edits modify that commit
- If @ is empty, your edits will become a new commit when you run
jj commit - Moving away from @ with
jj editsaves your working copy changes into @
Never assume working copy changes are separate from commits.
They are the same thing until you advance with jj commit.
Commit Workflow (Critical)
Always use jj commit -m to create commits.
Standard workflow:
# 1. Make changes and track new files
jj file track <new-files>
# 2. Verify changes
jj status
# 3. Commit and advance to new empty working commit
jj commit -m "$(cat <<'EOF'
Commit message
EOF
)"
# 4. Verify @ is empty
jj status # Should show "(empty)"Critical: After every commit, @ must be empty.
Never end on a non-empty working commit -
user's changes will auto-commit dangerously.
Empty Commits Are Normal
Do not panic when you see "(empty)" in jj status or jj log.
Empty commits are the standard state in jujutsu:
jj status
# Working copy (@) : abcd1234 (empty) (no description set)
# This is correct and expectedWhen @ is empty:
- You are ready to make new changes
- Next edits will become part of @
- When you
jj commit, those edits become @-
and @ advances to new empty commit
When @ is NOT empty:
- You have uncommitted changes that are part of @
- You should either
jj committo finalize them or continue editing - Never leave session with non-empty @ unless intentional
Empty commits are jujutsu's way of saying "ready for new work."
They are not errors or problems.
Amending Commit Messages
Use jj describe only to amend existing commit messages.
# Fix typo in current commit message
jj describe -m "Corrected message"
# Fix message in parent commit
jj describe -r @- -m "Corrected message"Never use jj describe + jj new to create commits.
That pattern is wrong - always use jj commit -m.
File Tracking
Critical: Users often disable auto-tracking.
After creating new files, always track them explicitly:
jj file track <path>Before committing, check status:
jj status # Shows untracked files with "?"Files marked with "?" are not included in commits.
You must track them first.
Pre-commit protocol:
- Check
jj status - Track any new files with
jj file track - Verify files show "A" (added) not "?" (untracked)
- Then commit
Never commit without checking status first.
Non-Interactive Commands
Always use non-interactive flags.
Creating new commits:
# Always use jj commit -m
jj commit -m "$(cat <<'EOF'
Subject line
Body text here.
EOF
)"Never use jj new alone -
it's only for special cases like creating empty commits on different branches.
Use HEREDOC for multi-line messages.
Common Anti-Patterns
Using jj describe + jj new to create commits (wrong pattern):
# Bad: Wrong pattern for creating commits
jj describe -m "message"
jj new
# Good: Always use jj commit
jj commit -m "message"Ending on non-empty working commit (dangerous):
# Bad: @ is non-empty after this
jj describe -m "message"
# User's next file changes auto-commit without warning!
# Good: @ is empty after jj commit
jj commit -m "message"
# User's changes are safe in new working commitUsing jj new when unnecessary:
# Bad: Creates empty commits
jj new # Almost never needed
# Good: Just use jj commit
jj commit -m "message"jj new is only for special cases (creating empty commits on branches).
Never use it in normal commit workflows.
Defaulting to git when jj available:
# Bad: User has jujutsu installed
git commit -m "message"
# Good: Use their preferred tool
jj commit -m "message"Interactive operations:
# Bad: Waits for user input
jj split
jj squash
jj squash -r <change>
# Good: Non-interactive with -m or -u flags
jj squash -m "New message" # Squash @ into parent with new message
jj squash -u # Squash @ into parent, keep message
jj squash -r <change> -m "message" # Squash specific change with message
jj squash -r <change> -u # Squash specific change, keep message
jj squash --into <dest> -m "msg" # Squash @ into dest with message
jj squash --into <dest> -u # Squash @ into dest, keep messageAlways use -m (new message) or -u (keep existing message).
Without these flags, commands open interactive editor.
Choosing between -m and -u:
Use -u when:
- Parent commit has correct message
- Adding forgotten files to existing commit
- Fixing minor omissions without changing intent
Use -m when:
- Parent message is wrong and needs replacement
- Combining changes requires new unified message
Common mistake: Using jj squash -m "add missing file" when parent has good message.
This replaces the parent's message instead of preserving it.
Always check parent message first: jj log -r @-
References
For advanced operations:
- See advanced-operations.md
for squashing safety, bookmark management, and git integration - See operation-log.md
for operation log safety net, undo vs restore, and recovery patterns
When Commands Require User Input
If operation needs user decision:
- State what decision is needed
- Ask user to specify
- Use their input in non-interactive command
Don't invoke interactive commands and wait.