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