using-jj
Use when the project uses jj (Jujutsu) for version control instead of git. Load this after `jj root` succeeds.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when the project uses jj (Jujutsu) for version control instead of git. Load this after `jj root` succeeds.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Use when the user says "capture", or wants to remember, save, or note something for later.
Use when the user says "closeday", "close my day", or "end of day". End-of-day consolidation appended to today's Inbox note.
Use when the user says "today", "morning plan", "plan my day", "what should I work on", or asks about their priorities for the day.
Use whenever `jj root` succeeds. Use `jj` for all version-control operations; do not use `git`.
Use when the user asks to create a GitHub issue, file a bug, or track a task. Also use when the user describes a problem they found and wants to capture it.
Use when the user asks to open a PR, create a PR, or push and create a pull request.
| name | using-jj |
| description | Use when the project uses jj (Jujutsu) for version control instead of git. Load this after `jj root` succeeds. |
This is a jj (Jujutsu) repository. Use jj for ALL version control operations. NEVER run git commands. If you don't know the jj equivalent of a git command, run jj help -- do not guess or fall back to git.
Do not use deprecated aliases: jj checkout (use jj edit), jj commit (use jj new), jj branch (use jj bookmark).
ALWAYS pass -m "message" to jj describe and jj squash. Without -m, these commands open $EDITOR and the agent will hang indefinitely.
jj describe -m "msg" -- ALWAYS use -mjj squash -m "msg" -- ALWAYS use -mjj new -- do NOT pass -m. It does not open an editor. Passing -m sets a description on the new empty change, which is almost never what you want. If the new change needs a description, use jj describe -m "msg" after jj new.Never use interactive commands: jj split, jj squash -i, and jj resolve will hang.
@). No staging area, no index. File changes are tracked automatically. There is no git add.jj new finalizes the current change and starts a new empty one on top. After jj new, @ is the new empty change and @- is the one you just finished.@ALWAYS run jj st or jj log before making any changes. The working copy IS a commit -- if @ already contains completed work and you start coding, you silently accumulate unrelated changes into it.
@ has completed work: jj new first, then jj describe -m "..."@ is empty: jj describe -m "..." then code@ is your in-progress work: continueDescribe before coding. The message comes first, then the code. Not after.
Understanding diff commands is essential. Getting them wrong makes it look like separate changes have been "merged into one."
-r vs --from/--to: Two completely different thingsjj diff -r <rev> shows what a single change introduced (the diff
between that revision and its parent). This is a patch view.jj diff --from A --to B compares file-tree snapshots at A and B.
This is NOT "the changes introduced by A through B." If A and B have
different parents or are on different branches, the result includes everything
that differs between the two trees -- not just what any particular set of
commits introduced. This is the #1 source of confusion.jj diff --git # what @ introduced (vs its parent)
jj diff --git -r <change-id> # what <change-id> introduced (vs its parent)
jj show --git <change-id> # same as above, but also shows description/metadata
To see what each change in a range introduced separately (one diff per change, not combined):
jj log -p --git -r <revset> # shows each change's own diff, one by one
jj log -p --git -r @---::@ # example: last 3 changes, each shown individually
jj log -p --git -r 'trunk()..@' # all changes since trunk, each shown individually
jj log -p is the correct way to review a series of changes. Each change is
displayed with its description and its own diff (what it introduced vs its
parent). Changes are NOT merged together.
If you genuinely want a single combined diff for everything a range of changes
introduced (like git diff A..B):
jj diff --git -r A::B # combined diff of all changes from A to B inclusive
This passes a multi-revision revset to -r, and jj computes the total diff.
It is equivalent to jj diff --git --from A- --to B (note: A- is A's
parent, so A's changes are included).
When to use which:
jj log -p --git -r <revset> (see each change separately)jj diff --git -r trunk()..@ (combined)jj diff --git --from A --to B (tree comparison)To see how a change has been modified (e.g. after amending or rebasing):
jj interdiff --git --from <old-rev> --to <new-rev>
jj evolog -p --git -r <change-id> # full evolution history of a change
jj interdiff compares patches (what two revisions each introduced),
rebasing the --from revision onto --to's parents first. This is different
from jj diff --from/--to which compares file-tree snapshots.
| Task | Command |
|---|---|
| Status | jj st |
| Diff (current change) | jj diff --git |
| Diff (specific rev) | jj diff --git -r <change-id> |
| Each diff in a range | jj log -p --git -r <revset> |
| Combined diff of range | jj diff --git -r A::B |
| Snapshot comparison | jj diff --git --from <rev> --to <rev> |
| Log | jj log |
| Show a revision | jj show --git <change-id> |
| Describe current change | jj describe -m "msg" |
| Start new change | jj new |
| Squash into parent | jj squash -m "msg" |
| Abandon change | jj abandon <change-id> |
| Undo last operation | jj undo |
| Restore files | jj restore [paths] |
| Rebase | jj rebase -r <rev> -d <dest> |
Always use --git with jj diff, jj show, and jj log -p -- the default color-words output is not machine-readable. --git gives standard unified diff format.
Verify after mutations -- run jj st after squash, abandon, rebase, restore.
Resolve conflicts by editing files directly, then jj st to verify. Do not use interactive resolution tools.
jj st -- check what @ containsjj describe -m "what I'm about to do" -- describe firstadd/stage step)jj new -- finalize and start the next changeBookmarks are jj's equivalent of git branches. They do NOT auto-advance on jj new.
Which revision to bookmark: After jj new, @ is the new empty change. Point bookmarks at @- (the completed change), not @. If you haven't run jj new yet, use @.
jj bookmark set <name> -r @- # create or move bookmark to completed change
jj git push -b <name> # push bookmark to remote
jj git fetch # fetch from remote
Always push via bookmark (-b). Never use jj git push -c. The -c flag creates auto-named bookmarks and pushes changes as separate branches instead of a single chain.
gh CLI works normally for PRs and issues.--head <bookmark-name> to gh pr create — without it gh cannot determine the branch in a jj repo.