| name | jujutsu |
| description | 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. |
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:
jj status
jj commit -m "message"
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 edit saves 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:
jj file track <new-files>
jj status
jj commit -m "$(cat <<'EOF'
Commit message
EOF
)"
jj status
Committing specific files (atomic commits):
When @ contains multiple independent changes,
use FILESETS to commit specific files:
jj commit -m "add feature X" path/to/file.rs path/to/other.rs
jj commit -m "update docs" README.md
This is the standard way to create atomic commits
from working copy changes.
Do not use jj split for this — jj commit FILESETS is simpler.
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
When @ 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 commit to 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.
jj describe -m "Corrected message"
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
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:
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.
Splitting Already-Committed Changes
Use jj split only for already-committed changes (not @).
For working copy changes on @,
use jj commit FILESETS instead (see Commit Workflow above).
jj split is for splitting a previous commit:
jj split -r @- -m "first part" path/to/file.zig
The second commit gets no description — describe or commit it next.
Never use bare jj split without filesets — it opens an interactive diff editor.
See advanced-operations.md for --parallel.
Common Anti-Patterns
Using jj describe + jj new to create commits (wrong pattern):
jj describe -m "message"
jj new
jj commit -m "message"
Ending on non-empty working commit (dangerous):
jj describe -m "message"
jj commit -m "message"
Using jj new when unnecessary:
jj new
jj commit -m "message"
jj new is only for special cases (creating empty commits on branches).
Never use it in normal commit workflows.
Always 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 splitting commits, 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