SKILL.md


name: using-jujutsu description: >- Guides jujutsu (jj) version control workflows and avoids common agent pitfalls. Use when the project uses jj or jujutsu for version control, when committing changes, creating new changes, or inspecting history with jj. Not for use with git repos. license: GPL-3.0-or-later metadata: author: Amolith amolith@secluded.site

Jujutsu (jj) is a Git-compatible VCS with a different mental model. This skill covers the non-obvious bits that trip agents up.

Never use --interactive

jj split --interactive, jj commit --interactive, jj squash --interactive, and any other --interactive flag open a TUI diff editor that agents cannot interact with. Always use path arguments to select files instead:

# Bad — hangs forever waiting for TUI input
jj commit --interactive -m "Add config parser"

# Good — selects specific files
jj commit -m "Add config parser" internal/config/config.go internal/config/config_test.go

If changes within a file ought to be split, politely ask the user to run split, give them the appropriate command, and include instructions on what to split. It's very easy, so having the user do the splits manually is no trouble :) It's worth it for nice, small, focused changes.

Specify files when committing

jj commit -m "msg" with no paths grabs everything in the working copy. This easily pulls in scratch files, experiments, or unrelated changes. Always list the files you intend to commit:

jj commit -m "Add snapshot screen" internal/ui/screens/snapshot.go internal/ui/screens/snapshot_test.go

The remaining changes stay in the new working-copy commit on top.

jj new vs jj commit

jj new and jj commit both create a new change, but they work differently:

  • jj new -m "msg" creates an empty change on top of the current one. The current change keeps all its content as-is.
  • jj commit -m "msg" [files] is like jj describe + jj new but lets you select which files stay in commit you're creating. The rest move to the new working-copy commit.

Use jj new when starting fresh work on top of a completed change. Use jj commit [files] when you want to finalize specific files and continue working on the rest. Use jj diff --summary to see what's changed before running either, so you don't accidentally leave changes in the previous commit that should move into the new working copy.

Use jj diff --git for readable diffs

The default jj diff output interleaves old and new lines in a format that is hard to parse. Always use jj diff --git for standard unified diffs:

# Hard to read
jj diff

# Standard unified diff format
jj diff --git

# Also works with revision arguments
jj diff --git -r usnrpsky

For a quick overview without the full diff, jj diff --summary (or -s) lists just the changed files with their M/A/D status. Prefer this over --stat when you only need to know which files changed:

jj diff --summary
# M cmd/root.go
# A internal/ui/screens/confirm.go
# A internal/ui/screens/confirm_test.go

--stat can still be useful at times.

Change IDs vs git commit hashes

jj uses short change IDs like usnrpsky for its own commands. Many external tools (code review CLIs, CI systems, etc.) need git SHAs instead. To get them:

# Show change IDs alongside git commit hashes
jj log --limit 5 -T 'change_id ++ " " ++ commit_id ++ "\n"'

# Just the git hash for a specific change
jj log -r usnrpsky -T 'commit_id ++ "\n"' --no-graph