1---
2name: using-jujutsu
3description: >-
4 Guides jujutsu (jj) version control workflows and avoids common agent
5 pitfalls. Use when the project uses jj or jujutsu for version control,
6 when committing changes, creating new changes, or inspecting history
7 with jj. Not for use with git repos.
8license: GPL-3.0-or-later
9metadata:
10 author: Amolith <amolith@secluded.site>
11---
12
13Jujutsu (jj) is a Git-compatible VCS with a different mental model. This skill
14covers the non-obvious bits that trip agents up.
15
16## Never use --interactive
17
18`jj split --interactive`, `jj commit --interactive`, `jj squash --interactive`,
19and any other `--interactive` flag open a TUI diff editor that agents cannot
20interact with. Always use path arguments to select files instead:
21
22```bash
23# Bad — hangs forever waiting for TUI input
24jj commit --interactive -m "Add config parser"
25
26# Good — selects specific files
27jj commit -m "Add config parser" internal/config/config.go internal/config/config_test.go
28```
29
30If changes within a file ought to be split, politely ask the user to run split,
31give them the appropriate command, and include instructions on what to split.
32It's very easy, so having the user do the splits manually is no trouble :) It's
33worth it for nice, small, focused changes.
34
35## Specify files when committing
36
37`jj commit -m "msg"` with no paths grabs everything in the working copy. This
38easily pulls in scratch files, experiments, or unrelated changes. Always list
39the files you intend to commit:
40
41```bash
42jj commit -m "Add snapshot screen" internal/ui/screens/snapshot.go internal/ui/screens/snapshot_test.go
43```
44
45The remaining changes stay in the new working-copy commit on top.
46
47## jj new vs jj commit
48
49`jj new` and `jj commit` both create a new change, but they work
50differently:
51
52- **`jj new -m "msg"`** creates an empty change on top of the current one. The
53 current change keeps all its content as-is.
54- **`jj commit -m "msg" [files]`** is like `jj describe` + `jj new` but lets you
55 select which files stay in commit you're creating. The rest move to the new
56 working-copy commit.
57
58Use `jj new` when starting fresh work on top of a completed change. Use `jj
59commit [files]` when you want to finalize specific files and continue working on
60the rest. Use `jj diff --summary` to see what's changed before running either,
61so you don't accidentally leave changes in the previous commit that should move
62into the new working copy.
63
64## Use jj diff --git for readable diffs
65
66The default `jj diff` output interleaves old and new lines in a format that is
67hard to parse. Always use `jj diff --git` for standard unified diffs:
68
69```bash
70# Hard to read
71jj diff
72
73# Standard unified diff format
74jj diff --git
75
76# Also works with revision arguments
77jj diff --git -r usnrpsky
78```
79
80For a quick overview without the full diff, `jj diff --summary` (or `-s`) lists
81just the changed files with their M/A/D status. Prefer this over `--stat` when
82you only need to know which files changed:
83
84```bash
85jj diff --summary
86# M cmd/root.go
87# A internal/ui/screens/confirm.go
88# A internal/ui/screens/confirm_test.go
89```
90
91`--stat` can still be useful at times.
92
93## Change IDs vs git commit hashes
94
95jj uses short change IDs like `usnrpsky` for its own commands. Many external
96tools (code review CLIs, CI systems, etc.) need git SHAs instead. To get them:
97
98```bash
99# Show change IDs alongside git commit hashes
100jj log --limit 5 -T 'change_id ++ " " ++ commit_id ++ "\n"'
101
102# Just the git hash for a specific change
103jj log -r usnrpsky -T 'commit_id ++ "\n"' --no-graph
104```