AGENT SKILL

jujutsu

Use this skill for any version control operations (commit, log, diff, push, fetch, bookmark, workspace, rebase, undo, etc.). If a `.jj` directory exists, the repo is jujutsu and git mutations will corrupt it — use `jj` for all mutations; read-only `git log/diff/show/blame/grep` are allowed. Covers co-located repos, multi-agent parallel workspaces, and operation-log recovery. **DO NOT IGNORE**

License 许可
Apache-2.0
最近更新
2026-05-21
Stars
★ 0
Forks
0

01 前言 Front Matter

name
jujutsu
license
Apache-2.0
metadata
{ "author": "johnstegeman", "version": "1.3" }
description
Use this skill for any version control operations (commit, log, diff, push, fetch, bookmark, workspace, rebase, undo, etc.). If a `.jj` directory exists, the repo is jujutsu and git mutations will corrupt it — use `jj` for all mutations; read-only `git log/diff/show/blame/grep` are allowed. Covers co-located repos, multi-agent parallel workspaces, and operation-log recovery. **DO NOT IGNORE**
allowed-tools
Bash(jj *)

02 资源文件 14

03 SKILL.md 正文

Jujutsu (jj) Version Control System

This skill helps you work with Jujutsu, a Git-compatible VCS with mutable commits and automatic rebasing.

Tested with jj v0.41.0 - Commands may differ in other versions.

For token-sensitive inspection commands, prefer the compact commands in references/TEMPLATES.md over jj's default output.

The compact commands in references/TEMPLATES.md intentionally use jj --no-pager ....

For revsets, filesets, and template syntax, see references/QUERY_LANGUAGES.md.

For sibling or unrelated work that should start from trunk(), see references/NONLINEAR.md.

For common surprises and easy mistakes, see references/GOTCHAS.md.

<!-- Attribution and inspiration sources:

Detecting a jj repo

Check whether a directory is part of a jj repo:

jj root

If it returns a path, the repo is jj-managed. If it returns Error: There is no jj repo in <directory>, it isn't. The presence of a .jj/ folder is another giveaway. If the repo is not a jj one, do not further use this skill.

<!-- Enforcement wording (allowed/forbidden split with read-only git allowlist) adapted from knoopx/pi@jujutsu. -->

Critical: never use git for mutations in a jj repo

In a jj repo (including co-located repos that also have .git/):

  • Forbidden (corrupts jj state): git commit, git add, git stash, git reset, git checkout <branch>, git switch, git rebase, git merge, git cherry-pick, git push, git pull.
  • Allowed (read-only): git log, git show, git diff, git blame, git grep, git status. Prefer the jj equivalents (jj log, jj show, jj diff, etc.) but read-only git commands won't break anything.
  • Use jj instead: jj git push, jj git fetch, jj edit <change> (not git checkout), jj rebase, jj new <a> <b> (for merges).

See references/COLOCATED.md for the full co-located repo workflow.

Important: Automated/Agent Environment

When running as an agent or running on behalf of the user:

  1. Always use -m flags to provide commit messages inline rather than relying on editor prompts:
# Always use -m to avoid editor prompts
jj desc -m "message"               # NOT: jj desc
jj squash --into @- -m "message"   # NOT: jj squash (which opens editor or prompts for hunks)

Editor-based commands will fail in non-interactive environments.

  1. Verify operations with jj st after mutations (squash, abandon, rebase, restore) to confirm the operation succeeded.

Important Principles

  1. Each commit should represent one logical change. See commit messages for details on good commit messages. Before starting work on a new change, make sure the working copy is clean (no changes)
jj st

Core Concepts

The Working Copy is a Commit

In jj, your working directory is always a commit (referenced as @). Changes are automatically snapshotted when you run any jj command. There is no staging area.

There is no need to run jj commit.

Commits Are Mutable

CRITICAL: Unlike git, jj commits can be freely modified. This enables a high-quality commit workflow:

  1. Before starting work, run jj st. If @ already has changes, run jj new first. If @ is empty, use it as-is.
  2. Describe your intended changes with jj desc -m "Message"
  3. Make your changes.
  4. Do NOT run jj new when finished — leave that to the next task's step 1.

You may refine the commit using jj squash or jj absorb as needed

Change IDs vs Commit IDs

  • Change ID: A stable identifier (like tqpwlqmp) that persists when a commit is rewritten
  • Commit ID: A content hash (like 3ccf7581) that changes when commit content changes

Prefer using Change IDs when referencing commits in commands.

Essential Workflow

Starting Work: Describe First, Then Code

Always create your commit message before writing code:

# First, describe what you intend to do
jj desc -m "feat: Add user authentication to login endpoint"

# Then make your changes - they automatically become part of this commit
# ... edit files ...

# Check status
jj st

For the full starting-a-change workflow (when to reuse @ vs jj new, anti-patterns, decision logic), see references/NEW_CHANGE.md.

For unrelated or sibling work that should branch from trunk(), see references/NONLINEAR.md.

Creating Atomic Commits

Each commit should represent ONE logical change.

Viewing History

# View recent commits
jj log

# View with patches
jj log -p

# View specific commit
jj show <change-id>

# View diff of working copy
jj diff

If you need to run jj log, jj show, or jj diff as an agent, use the matching compact command from references/TEMPLATES.md unless the full default output is explicitly needed.

For the revsets, filesets, and template syntax behind those compact commands, see references/QUERY_LANGUAGES.md.

Moving Between Commits

# Create a new empty commit on top of current
jj new

# Create new commit with message
jj new && jj desc -m "Commit message"

# Edit an existing commit (working copy becomes that commit)
jj edit <change-id>

# Edit the previous commit
jj prev -e

# Edit the next commit
jj next -e

Refining Commits

If you need to refine a commit (squash, abandon, undo, split, etc), see (Refining commits)[references/REFINE_COMMIT.md]

Working with Bookmarks (Branches)

Bookmarks are jj's equivalent to git branches:

# Create a bookmark at current commit
jj bookmark create my-feature -r@

# Move bookmark to a different commit
jj bookmark move my-feature --to <change-id>

# List bookmarks
jj bookmark list

# Delete a bookmark
jj bookmark delete my-feature

If you need to run jj bookmark list, use the matching compact command from references/TEMPLATES.md.

<!-- Multi-agent workspace framing inspired by onevcat/skills@onevcat-jj. The .workspaces/ project-local convention codified in references/WORKSPACES.md is adapted from edmundmiller/dotfiles using-jj-workspaces. -->

Parallel Workspaces

For running multiple agents in parallel against the same repo without working-copy collisions, use jj workspace. Each workspace gets its own @ while sharing the underlying repo store.

# Quick reference (full convention in references/WORKSPACES.md)
jj workspace add .workspaces/<repo>-<purpose>   # Create
jj workspace list                                # List
jj workspace forget <name>                       # Untrack (files stay on disk)

If you need to run jj workspace list, use the matching compact command from references/TEMPLATES.md.

See references/WORKSPACES.md for the full convention: the .workspaces/ directory layout, .gitignore safety check, naming, environment bootstrapping, agent handoff, monitoring, stale-workspace recovery, and merging results from multiple workspaces back together.

Working with tags

jujutsu does not yet support tags and pushing them to a remote. If you need to tag (such as for a release), you will need to use git to create and push the tags.

Git Integration (Co-located Repos)

Always use co-located repos when working with existing git projects. They give you jj locally while keeping the repo remote-compatible with git tooling.

jj git clone <url> --colocate           # Clone a git repo
jj git init --colocate                  # Adopt an existing git repo

See references/COLOCATED.md for the complete workflow: the mutation rule (git is forbidden for mutations, allowed read-only), the git-command allowlist, common gotchas, and switching modes when absolutely necessary.

See references/GOTCHAS.md when the behavior feels surprising and you want the short list of jj-specific footguns before trying a git-style workaround.

Pushing Changes

For pushing bookmarks to a remote, see references/PUSH.md. For named remotes, fork+upstream setups, and other multi-remote workflows, see references/REMOTES.md.

Handling Conflicts

jj treats conflicts as first-class objects — a commit can contain a conflict, and that conflict persists through rebases until resolved. jj refuses to push conflicted commits, so they must be resolved before jj git push.

jj st                                # Reports if @ has unresolved conflicts
jj resolve --list                    # Lists conflicted paths
jj resolve --tool :ours              # Take side #1 non-interactively (agent-safe)
jj resolve --tool :theirs            # Take side #2 non-interactively (agent-safe)

Never run bare jj resolve (no --tool) — it's interactive and will hang in non-interactive agent environments. Either pass --tool :ours / --tool :theirs, or edit conflict markers directly in the file and let jj st snapshot the resolution.

See references/CONFLICTS.md for the full resolution playbook: marker formats (diff vs snapshot), five resolution paths, ancestor-level resolution to avoid re-resolving across descendants, verification (beyond jj st), and anti-patterns.

<!-- Recovery framing ("op log records every mutation; nothing is ever lost") adapted from trevors/dot-claude@jj-workflow. -->

Recovery and the Operation Log

The op log records every mutation. Nothing is ever lost.

jj undo                  # Reverse the last operation (primary recovery tool)
jj op log                # See all operations
jj op restore <op-id>    # Jump back to any past state
jj evolog -r <change>    # See how a specific change evolved

If you need to run jj op log or jj evolog, use the matching compact commands from references/TEMPLATES.md first. Add -p only after you have narrowed the scope.

Always reach for jj undo first when something looks wrong — it's always correct and safe. See references/RECOVERY.md for recovery patterns by scenario (bad squash, accidental abandon, lost work, etc.).

Preserving Commit Quality

IMPORTANT: Because commits are mutable, always refine them:

  1. Review your commit: jj show @ or jj diff
  2. Is it atomic? One logical change per commit
  3. Is the message clear? Use imperative verb phrase in sentence case format with no full stop: "Verb object"
  4. Are there unrelated changes? Use jj restore to move changes out, then create separate commits
  5. Should changes be elsewhere? Use jj squash or jj absorb

Quick Reference

Action Command
Describe commit jj desc -m "message"
View status jj st
View log jj log
View diff jj diff
New commit jj st then jj new only if @ has changes, then jj desc -m "message"
Edit commit jj edit <id>
Squash to parent jj squash --into @- -m "message"
Auto-distribute jj absorb
Abandon commit jj abandon <id>
Undo last operation jj undo
Restore files jj restore [paths]
Create bookmark jj bookmark create <name>
Push bookmark jj git push -b <name>
Add workspace jj workspace add .workspaces/<repo>-<purpose>
List workspaces jj workspace list
Forget workspace jj workspace forget <name>
See operation log jj op log
Jump to past state jj op restore <op-id>
See change evolution jj evolog -r <id>

Best Practices Summary

  1. Describe first: Set the commit message before coding
  2. One change per commit: Keep commits atomic and focused
  3. Use change IDs: They're stable across rewrites
  4. Refine commits: Leverage mutability for clean history
  5. Embrace the workflow: No staging area, no stashing — the op log replaces both
  6. Workspaces for parallel agents: Isolate concurrent agent work in .workspaces/<repo>-<purpose> (see references/WORKSPACES.md)
  7. jj undo first: When something looks wrong, undo before fixing manually (see references/RECOVERY.md)

04 同仓库更多 Skills