jujutsu
Use when planning or running version-control operations: jj for every write and history edit, git for reads only. Covers non-interactive use, side-effect-free reads (templates, filesets, past operations), precise history edits (split, squash, absorb, rebase, inserting without moving @), recovering e…
Install / Use
npx skills add takeokunn/nixos-configuration --skill jujutsuInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
MarketingSupported Platforms
Our assessment of jujutsu
jujutsu scores 63/100 on our quality scale, 568th of 588 Marketing skills we index.
Its SKILL.md is 17 KB long, well organised into 13 sections and no code examples: a thorough specification that gives an agent plenty to work with.
It has no GitHub stars yet, so there is no community track record; judge it on its content.
Maintenance, license and trust
- We could not determine when the repository was last updated.
- No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
- Its trust signals score 68/100, with 3 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.
AI review by kimi-k2.7-code on 2026-11-07. Automated pattern scan on 2026-11-07. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
jujutsu compared with similar skills
All 4 of these similar skills score higher than jujutsu; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| jujutsu (this skill)by takeokunn | 63 | 0 | — | SKILL.md |
| Agent-Reachby Panniantong | 100 | 109.8k | 1d ago | CLAUDE.md |
| algorithmic-artby anthropics | 100 | 177.9k | 45d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 45d ago | SKILL.md |
| designby nextlevelbuilder | 100 | 143.4k | 7d ago | SKILL.md |
Frequently asked questions
- How do I install jujutsu?
- Run
npx skills add takeokunn/nixos-configuration --skill jujutsu. The install tabs above show the steps for each supported agent. - Which AI agents does jujutsu work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is jujutsu safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It declares no license and scores 68/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is jujutsu still maintained?
- We could not determine when the repository was last updated.
Skill content
View source on GitHubname: jujutsu description: "Use when planning or running version-control operations: jj for every write and history edit, git for reads only. Covers non-interactive use, side-effect-free reads (templates, filesets, past operations), precise history edits (split, squash, absorb, rebase, inserting without moving @), recovering earlier versions without undo, conflicts recorded in commits, revset checks, the operation log, shared working copies, stale workspaces, bisect, bookmarks and stacks, and pre-push checks." metadata: version: "1.4.0"
Jujutsu (jj)
A .jj/ directory at the root of the checkout you work in means jj is in use: run all version-control
operations through jj and keep GitHub operations on gh. Git is read-only; CLAUDE.md gives the rule, including
what to do when .jj/ is missing. A .worktrees/ directory under a bare repository without its own .jj/ is
not a jj workspace: jj root succeeds there but names the bare root, whose jj sees none of the directory's
files, and jj status shows no changes.
Two layouts carry .jj/:
- A non-bare clone is colocated:
.jj/and.git/share one Git object store, jj exports its changes to Git refs, and Git's HEAD is left detached. Write through jj; read-only git subcommands also work. - A bare
<repo>.git/holds jj's store at its root in an empty-sparsedefaultworkspace that tracks no files. Work happens in jj workspaces under.worktrees/, which have no.gitof their own. A gate that enumerates files through git (git ls-files, treefmt's default walker) there checks nothing and exits 0. Confirm its input count, or run it with a filesystem walk (treefmt --walk filesystem).
Local jj writes on a non-default change (commit, describe, split, squash, absorb, rebase of your own changes,
bookmark create, fetch, workspace add) need no separate authorization when the task calls for them. Push, and
any write to the default branch, need the user's confirmation; so does moving or discarding a shared working
copy (CLAUDE.md hard_rules).
Before the first commit in a repository, run jj config get user.email there and confirm the value. Jujutsu
does not read Git's conditional includeIf identity configuration.
The working copy is a commit
jj has no staging area. Repository commands normally snapshot files on disk into the working-copy revision @,
so jj status records edits as well as reporting them. In a checkout shared with other sessions, that snapshot
absorbs their edits into @ too: before describing, squashing, or pushing @, read jj diff --git and
confirm every hunk is yours. Pass --ignore-working-copy to read-only commands to avoid snapshotting shared
edits, but their view may be stale. To read on-disk state, run jj status or jj diff --git without the flag:
before committing, to separate your changes from existing ones, or at completion to confirm the changed files,
not as a routine first step.
Confirm a remote ref before relying on a fetched one: compare jj log --ignore-working-copy -r '<b>@<remote>' --no-graph -T 'commit_id' with gh api repos/<owner>/<repo>/git/ref/heads/<branch> --jq .object.sha (tags:
git/ref/tags/<tag>). A remote-tracking ref left by a fetch without explicit --remote and --branch is not
freshness evidence.
A change has a stable change ID (letters k-z) and a commit ID that changes on every rewrite. Refer to changes by change ID across rewrites.
Command map
Run only the jj column.
| Git habit | jj |
|---|---|
| git status | jj status |
| git log --oneline --graph | jj log |
| git diff / git diff --cached | jj diff --git (no staging, one diff) |
| git show <rev> | jj show --git <rev> |
| git add + git commit -m | jj commit -m "<msg>" (describes @, starts a new empty @) |
| git commit --amend -m | jj describe -m "<msg>" |
| git commit --amend --no-edit (fold in edits) | jj squash (moves @ into its parent) |
| git add -p + commit (some files) | jj split -m "<msg>" <paths> |
| git commit --fixup + autosquash | jj absorb [<paths>] |
| git checkout -b <b> | jj bookmark create <b> -r @ |
| git branch -f <b> <rev> | jj bookmark set <b> -r <rev> (-B to move it backwards or sideways) |
| git fetch | jj git fetch --remote <r> --branch <b> (always name both) |
| git push origin <b> | jj git push -b <b> (see Pushing) |
| git rebase <onto> | jj rebase -b @ -o <onto> (-o is --onto) |
| git cherry-pick <sha> | jj duplicate <rev> -o <dest> |
| git revert <sha> | jj revert -r <rev> -o @ |
| git checkout -- <path> | jj restore <path> |
| git blame <file> | jj file annotate <file> |
| git reflog | jj op log |
Non-interactive use
- Always pass
-mtojj commit,jj describe, andjj split; without it they open an editor. Forjj squash, pass-mor-u(keep the destination's message) when both sides carry descriptions. jj splitwith paths selects those files without a diff editor; without paths it opens one. Never runjj splitwithout paths,jj diffedit,jj resolvewithout--list, or any-i/--interactiveform. The guardrail hook does not catch these; an editor waiting for input hangs the call.- Add
--no-pagerto output-producing commands, and--gitto diff commands whose output will be parsed: the default diff formatter here is difftastic. - For machine-readable output, pass
--no-ext-difftogit diffso configured external diff drivers cannot alter its output. - For scripted reads,
jj log --no-graph -r <revset> -T '<template>'gives stable output.
Reading without side effects
These read the repository without moving @ or rewriting a commit. Each still snapshots the files on disk
into @ first unless you add --ignore-working-copy:
-T 'json(self) ++ "\n"'prints one JSON object per commit (change and commit IDs, parents, description, author, committer). For a narrower line, combine the keywordschange_id.shortest(),commit_id.short(),description.first_line(),bookmarks,empty,conflict,divergent, andimmutable.- Path arguments are filesets:
jj diff --git -r <rev> 'glob:"**/*.nix" & ~glob:"flake.nix"'limits a diff to the matching files. A bare path matches that file or directory relative to the current directory. jj file show -r <rev> <path>prints a file as it was in a revision, andjj file list -r <rev>lists the tracked files there. Neither touches the files on disk.jj --at-op <op> log -r <revset>shows the repository as it was after an earlier operation, without restoring it. Take<op>fromjj op log.
Editing history precisely
Each command below rewrites mutable commits and rebases their descendants automatically; none touches
immutable() commits (by default trunk(), tags, and untracked remote bookmarks) without --ignore-immutable,
which needs its own explicit request.
- Move part of a change:
jj squash --from <src> --into <dest> <paths>moves only those paths. Without paths it moves everything and abandons an emptied, undescribed source;-kkeeps it. - Distribute fixups:
jj absorbsends each hunk of@to the closest mutable ancestor that last modified those lines, and leaves a hunk in place when the destination is ambiguous. Review where every hunk went withjj op show -pbefore building on the result; move a misplaced one withjj squash --from <wrong> --into <right> <path>, since the guardrail hook blocksjj undo. - Rebase by scope:
-r <rev>moves one commit and reparents its children onto its parent;-s <rev>moves it with its descendants;-b <rev>moves the whole branch relative to the destination.-A/-Binsert instead of stacking on top. Choosing-rwhen-swas meant strands the descendants on the old base. - Reorder independent commits:
jj parallelize <a>::<b>makes a linear run into siblings. - Edit a commit other than
@: most rewrites take-r.jj describe -r <rev> -m "<msg>"rewords it,jj split -r <rev> -m "<msg>" <paths>splits it (--parallelmakes the two halves siblings), andjj squash -r <rev>folds it into its parent. - Insert without moving
@:jj new --no-edit -A <rev> -m "<msg>"creates an empty commit after<rev>and rebases<rev>'s children onto it;-Binserts before.jj new --no-edit <a> <b> -m "<msg>"creates a merge of the two.--no-editis what the guardrail hook allows: without it,jj newonto another revision moves@and is blocked. - Copy content between revisions:
jj restore --from <src> --into <dest> <paths>gives those paths in<dest>the content they have in<src>. Paths are required, as in everyjj restorethe hook allows. - Clean up merges:
jj simplify-parents -r <rev>drops a parent that is also an ancestor through another parent, without changing any content.
Recovering an earlier version
The guardrail hook blocks jj undo and jj op restore, so recover by reading the old state and rewriting
forward:
jj evolog -r <change> -p --gitlists each earlier commit of the change with its patch.jj op logandjj --at-op <op> loglocate the state before a bad operation. A rewritten commit stays addressable by its old commit ID, as a hidden commit.jj interdiff --from <old-commit-id> --to <change> --gitshows how the two versions' changes differ.jj restore --from <old-commit-id> --into <change> <paths>brings back the old content of those paths, orjj duplicate <old-commit-id> -o <dest>recreates the whole old version as a new change.
Conflicts are commits, not stops
A rebase or squash that conflicts still exits 0: jj records the conflict inside the commit and carries on,
and every descendant inherits it. An exit status is therefore no evidence a rewrite succeeded. After any
rewrite, compare the old and new tips with jj interdiff --from <old-tip> --to <new-tip> --git, then run
jj log --no-graph -r 'conflicts()' before pushing. The conflict query must print nothing. In a clean @,
jj resolve --list exits 2 with "No conflicts found", so its nonzero exit is the passing result there.
When @ is the conflicted commit, edit the conflict markers in the files directly and the next snapshot
records the resolution. When the conflict sits in an ancestor, jj suggests jj new <conflicted>, which the
guardrail hook blocks. If one side is right for a whole file, resolve it in place with
jj resolve -r <conflicted> --tool :ours <path> (:theirs for the other side); a permission rule makes any
--tool form prompt the user. For a manual resolution, keep @ on its current descendant, edit the conflict
markers in its file, then run jj squash --into <conflicted> <paths> from the repository root. The squash
moves the resolution into the ancestor and leaves a new empty @ child. Run
jj log --no-graph -r 'conflicts()' to confirm that no conflicts remain. Otherwise report the conflicted
change IDs and ask the user to resolve them or to approve a separate workspace for it.
Revsets that answer checks
Confirm what trunk() resolves to (jj log -r 'trunk()') before using it as a range bound. A clone may carry
a per-repository alias (jj config list 'revset-aliases."trunk()"' shows it); otherwise the built-in tries
main, master, and trunk on origin and then upstream, and with none of them it resolves to the root
commit, so trunk()..@ silently spans the whole history.
| Question | Revset |
|---|---|
| My unpushed stack | trunk()..@ |
| Anything conflicted | conflicts() |
| One change rewritten by two sessions | divergent() |
| Leftover empty commits | empty() & mutable() & ~merges() & ~working_copies() |
| Commits touching a path | files("<path>") |
| Find by message | description(substring:"<text>") |
| Tips of mutable work | heads(mutable()) |
| Commits whose diff mentions a string | `diff_lines("<text>", "<path>"
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
109.8kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
design
143.4kComprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini, Atlas Cloud, or MuAPI AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social/ads/web/print), icon design (15 styles, SVG…
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
