onevcat-jj
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesejj (Jujutsu) — Version Control for Agent Workflows
jj(Jujutsu)—— 适用于 Agent 工作流的版本控制工具
jj is a version control tool that coexists with Git. You use jj locally; the remote is still standard Git. GitHub and collaborators see ordinary git commits and branches.
This skill teaches you how to use jj correctly and idiomatically, especially in agent-assisted development workflows.
jj 是一款可与 Git 共存的版本控制工具。你可以在本地使用 jj,而远程仓库仍采用标准 Git 架构。GitHub 平台及协作者看到的将是普通的 Git 提交与分支。
本技能将教你如何正确、地道地使用 jj,尤其是在 Agent 辅助的开发工作流中。
Core Mental Model
核心思维模型
jj revolves around changes, not branches. Key differences from Git:
- No staging area. File modifications are automatically part of the current change. There is no .
git add - No stash. Just to start fresh work; previous changes stay where they are.
jj new - No detached HEAD. lets you jump to any change and keep working; descendants auto-rebase.
jj edit - Branches are called bookmarks and are only needed when pushing to a remote.
The working copy IS a change. Every file modification is instantly tracked in the current change.
jj 围绕**变更(changes)**而非分支展开。与 Git 的主要区别:
- 无暂存区:文件修改会自动成为当前变更的一部分,无需执行 命令。
git add - 无暂存(stash)功能:只需执行 即可开始新的工作,之前的变更会保留在原位。
jj new - 无游离 HEAD 状态:允许你切换到任意变更并继续工作,其后续变更会自动完成变基。
jj edit - 分支被称为bookmark(书签):仅在推送到远程仓库时才需要使用。
工作区本身就是一个变更。所有文件修改都会立即被追踪到当前变更中。
Detecting a jj Repo
检测 jj 仓库
Before performing version control operations, check if the repo uses jj:
bash
undefined执行版本控制操作前,请先检查仓库是否使用 jj:
bash
undefinedIf .jj/ exists, use jj commands — not git commands
若 .jj/ 目录存在,请使用 jj 命令而非 Git 命令
test -d .jj && echo "jj repo"
When a repo has both `.jj/` and `.git/` (colocated mode), always prefer jj commands for local operations.test -d .jj && echo "jj repo"
当仓库同时存在 `.jj/` 和 `.git/` 目录(共存模式)时,本地操作请优先使用 jj 命令。Setup
初始化配置
To initialize jj in an existing Git repo (colocated mode — keeps alongside ):
.git/.jj/bash
jj git init --colocateAfter init, you may need to track remote bookmarks so jj knows about remote branches:
bash
jj bookmark track master@origin # Track a specific remote branchjj will usually hint you about this if it's needed.
在已有的 Git 仓库中初始化 jj(共存模式 —— 保留 .git/ 目录与 .jj/ 目录并存):
bash
jj git init --colocate初始化完成后,你可能需要追踪远程书签,让 jj 知晓远程分支的存在:
bash
jj bookmark track master@origin # 追踪指定的远程分支若有需要,jj 通常会主动提示你执行该操作。
Essential Commands
核心命令
Inspect State
查看仓库状态
bash
jj log # Show change graph + status (replaces git log + git status)
jj diff # Show diff of current change vs parent
jj diff -r <change> # Show diff of a specific changejj log@kxryzmspkxkxryzmspbash
jj log # 显示变更图谱及状态(替代 git log + git status)
jj diff # 显示当前变更与父变更的差异
jj diff -r <change> # 显示指定变更的差异jj log@kxryzmspkxkxryzmspWork on Changes
处理变更
bash
jj describe -m "feat: add auth module" # Set/update description of current change
jj describe -r <change> -m "new msg" # Update description of any change
jj new # Finish current change, start a new empty one
jj new <change> # Start new work branching from a specific change
jj commit -m "feat: ..." # Shorthand: describe current + start new (equivalent to describe + new)
jj edit <change> # Jump to an existing change and continue editing it
jj abandon # Discard the current change entirely
jj abandon <change> # Discard a specific changejj newjj abandonjj editAfter , modifying files amends that change in place. All descendant changes auto-rebase — you never need to manually rebase after editing an ancestor.
jj editbash
jj describe -m "feat: add auth module" # 设置或更新当前变更的描述
jj describe -r <change> -m "new msg" # 更新指定变更的描述
jj new # 完成当前变更,创建一个新的空变更
jj new <change> # 基于指定变更创建新的工作分支
jj commit -m "feat: ..." # 快捷操作:描述当前变更并创建新变更(等效于 describe + new)
jj edit <change> # 切换到已有变更并继续编辑
jj abandon # 完全丢弃当前变更
jj abandon <change> # 丢弃指定变更jj newjj abandonjj edit执行 后,修改文件会直接在该变更上进行追加。所有后续变更会自动完成变基——你永远无需在编辑祖先变更后手动执行变基操作。
jj editReorganize History
重构历史
bash
jj split # Interactively split current change into two (or more)
jj split -r <change> # Split a specific change
jj rebase -s <source> -d <destination> # Move a change (and its descendants) to a new parent
jj rebase -d <destination> # Rebase current branch onto destination
jj undo # Undo the last jj operation (any operation)
jj op log # View operation-level history
jj op restore <operation-id> # Restore repo to any previous operation statejj splitjj undobash
jj split # 交互式地将当前变更拆分为两个(或多个)变更
jj split -r <change> # 拆分指定变更
jj rebase -s <source> -d <destination> # 将一个变更(及其后续变更)移动到新的父变更
jj rebase -d <destination> # 将当前分支变基到目标变更
jj undo # 撤销上一次 jj 操作(任意操作均可撤销)
jj op log # 查看操作级别的历史记录
jj op restore <operation-id> # 将仓库恢复到任意历史操作状态默认情况下(未指定文件集时), 会打开交互式编辑器。你可以选择哪些文件/代码块属于第一个变更,剩余内容会自动成为第二个变更。重复执行可进一步拆分。
jj splitjj undoRemote Interaction (Git Bridge)
远程交互(Git 桥接)
bash
jj git fetch # Fetch from remote (like git fetch)
jj rebase -d master # Rebase current work onto latest master
jj bookmark track master@origin # Track a remote branch (needed after init or for new remotes)
jj bookmark create my-feature -r @ # Create a bookmark (= git branch) pointing at current change
jj bookmark create my-feature -r <chg> # Create a bookmark pointing at a specific change
jj bookmark set my-feature -r <change> # Move an existing bookmark to a different change
jj git push # Push all changed bookmarks to remote
jj git push --bookmark my-feature # Push only a specific bookmark
jj git push --deleted # Push bookmark deletions to remote (after jj abandon)Remote Git branches are automatically mapped to jj bookmarks on fetch. The (or ) you see in IS the remote branch, accessed via bookmark.
mastermainjj logAfter or when a new remote branch appears, you may need to tell jj to follow it. jj will hint you when this is needed.
jj git init --colocatejj bookmark track <name>@<remote>Workflow for pushing:
- Finish your work (describe the change)
- — give it a Git branch name
jj bookmark create <name> -r <change> - — push to remote (or
jj git pushfor just one)--bookmark <name>
Cleanup after abandoning a pushed change:
When you a change that had a bookmark pushed to remote, the bookmark is deleted locally. Use to sync that deletion to the remote.
jj abandonjj git push --deletedbash
jj git fetch # 从远程仓库拉取代码(类似 git fetch)
jj rebase -d master # 将当前工作变基到最新的 master 分支
jj bookmark track master@origin # 追踪远程分支(初始化后或新增远程分支时需要执行)
jj bookmark create my-feature -r @ # 创建一个书签(等效于 Git 分支)指向当前变更
jj bookmark create my-feature -r <chg> # 创建一个书签指向指定变更
jj bookmark set my-feature -r <change> # 将已有书签移动到另一个变更
jj git push # 将所有已修改的书签推送到远程仓库
jj git push --bookmark my-feature # 仅推送指定的书签
jj git push --deleted # 将书签的删除操作推送到远程仓库(执行 jj abandon 后需要)拉取远程代码时,Git 远程分支会自动映射为 jj 的bookmark(书签)。你在 中看到的 (或 )就是远程分支,通过书签访问。
jj logmastermain执行 后或出现新的远程分支时,你可能需要执行 让 jj 追踪该分支。当需要执行此操作时,jj 会主动提示你。
jj git init --colocatejj bookmark track <name>@<remote>推送工作流:
- 完成工作(描述变更)
- —— 为其设置一个 Git 分支名称
jj bookmark create <name> -r <change> - —— 推送到远程仓库(或使用
jj git push仅推送指定分支)--bookmark <name>
丢弃已推送变更后的清理:
当你使用 丢弃一个已推送到远程仓库的变更时,对应的书签会在本地被删除。执行 可将该删除操作同步到远程仓库。
jj abandonjj git push --deletedParallel Workspaces
并行工作区
bash
jj workspace add ../workspace-name # Create a parallel workspace (like git worktree)Each workspace gets its own directory but shares the underlying repository store. Multiple agents can work in separate workspaces simultaneously from the same base, then merge results with .
jj new <change1> <change2> ...bash
jj workspace add ../workspace-name # 创建并行工作区(类似 git worktree)每个工作区都有独立的目录,但共享底层的仓库存储。多个 Agent 可以同时在同一仓库的不同并行工作区中工作,之后通过 合并结果。
jj new <change1> <change2> ...Agent Workflow Patterns
Agent 工作流模式
These patterns leverage jj's strengths for agent-assisted development.
以下模式充分利用了 jj 的特性,适用于 Agent 辅助的开发工作。
Pattern 1: Start Next Task
模式 1:开启新任务
Just and begin. No need to add, commit, push, or create a branch first. The previous change is automatically preserved.
jj newbash
jj new
jj describe -m "feat: implement avatar upload"只需执行 即可开始工作。无需先执行添加、提交、推送或创建分支等操作,之前的变更会被自动保留。
jj newbash
jj new
jj describe -m "feat: implement avatar upload"start working...
开始工作...
undefinedundefinedPattern 2: Interrupt and Resume
模式 2:中断与恢复
To handle an urgent task mid-work:
bash
jj new master # Branch off master for the urgent fix在工作中途处理紧急任务:
bash
jj new master # 基于 master 分支创建新变更以处理紧急修复... do the fix ...
... 完成修复 ...
jj describe -m "fix: critical auth bug"
jj edit <previous-change> # Jump back to where you were
jj describe -m "fix: critical auth bug"
jj edit <previous-change> # 切换回之前的变更继续工作
... resume previous work ...
... 恢复之前的工作 ...
No stash, no branch switching, no state to restore.
无需暂存、切换分支或恢复状态。Pattern 3: Split After the Fact
模式 3:事后拆分
After producing a large change, split it into logical pieces:
bash
jj split # Interactive: pick files/hunks for first change, rest goes to second
jj split # Split again if neededIf a split goes wrong, and try again.
jj undo完成一个大型变更后,将其拆分为多个逻辑独立的变更:
bash
jj split # 交互式操作:选择文件/代码块属于第一个变更,剩余内容自动成为第二个变更
jj split # 若需要可继续拆分如果拆分操作出错,执行 后重新尝试即可。
jj undoPattern 4: Skeleton Planning (Recommended for Complex Tasks)
模式 4:骨架规划(推荐用于复杂任务)
Create empty changes as a plan, then fill them in order:
bash
jj commit -m "refactor: extract auth module"
jj commit -m "feat: add token refresh logic"
jj commit -m "test: update auth tests"
jj commit -m "docs: update API documentation"Then work through them:
bash
jj edit <first-change> # Jump to first skeleton change先创建空变更作为计划,再按顺序填充内容:
bash
jj commit -m "refactor: extract auth module"
jj commit -m "feat: add token refresh logic"
jj commit -m "test: update auth tests"
jj commit -m "docs: update API documentation"然后逐个实现:
bash
jj edit <first-change> # 切换到第一个骨架变更... implement ...
... 实现内容 ...
jj edit <next-change> # Jump to next (previous work auto-rebases descendants)
jj edit <next-change> # 切换到下一个变更(之前的工作会自动为后续变更完成变基)
... implement ...
... 实现内容 ...
Each change's description serves as both the commit message and the acceptance criteria. Verify your implementation matches the description before moving on.
The description field supports the same format as git commit messages: first line is the title, blank line, then body. You can write detailed specs or prompts in the body with `-m`.
每个变更的描述既作为提交信息,也作为验收标准。在切换到下一个变更前,请确保你的实现与描述一致。
描述字段支持与 Git 提交信息相同的格式:第一行为标题,空行后为正文。你可以使用 `-m` 参数在正文中编写详细的规格说明或提示信息。Pattern 5: Undo and Recover
模式 5:撤销与恢复
bash
jj undo # Undo last operation, no questions asked
jj op log # See full operation history if you need to go further back
jj op restore <op-id> # Jump to any point in operation historyPrefer over trying to manually reverse changes. It is always correct and safe.
jj undobash
jj undo # 撤销上一次操作,无需额外确认
jj op log # 查看完整的操作历史,若需要恢复到更早的状态
jj op restore <op-id> # 切换到任意操作历史状态优先使用 而非手动撤销变更,它始终是正确且安全的。
jj undoCommon Mistakes to Avoid
常见错误规避
- Do not use ,
git add,git commit, orgit stashin a jj repo. Use jj equivalents instead.git checkout - Do not try to an immutable (published) change without good reason. jj will block this. If you need to fix something in published history, use
jj editto create a follow-up change instead.jj new <change> - Do not create bookmarks for local-only work. Bookmarks are only needed when pushing to remote. Local work is tracked by Change IDs.
- Do not worry about "losing" changes. jj's operation log preserves everything. Use or
jj undoto recover from any mistake.jj op restore
- 请勿在 jj 仓库中使用 、
git add、git commit或git stash命令,请使用对应的 jj 命令替代。git checkout - 请勿尝试 不可变(已发布)的变更,除非有充分理由。jj 会阻止此操作。若需要修复已发布历史中的内容,请使用
jj edit创建一个后续变更。jj new <change> - 请勿为仅本地的工作创建书签,书签仅在推送到远程仓库时才需要使用。本地工作通过变更 ID 追踪。
- 无需担心“丢失”变更,jj 的操作日志会保留所有内容。使用 或
jj undo可从任何错误中恢复。jj op restore
Quick Reference
快速参考
| Task | jj command |
|---|---|
| Initialize in existing git repo | |
| See what's going on | |
| Describe current change | |
| Start next task | |
| Branch from specific change | |
| Edit an older change | |
| Discard a change | |
| Split a change | |
| Undo anything | |
| Fetch remote | |
| Track a remote branch | |
| Rebase onto master | |
| Create bookmark for push | |
| Move existing bookmark | |
| Push to remote | |
| Push specific bookmark | |
| Push bookmark deletions | |
| Merge multiple changes | |
| Parallel workspace | |
| 任务 | jj 命令 |
|---|---|
| 在已有 Git 仓库中初始化 jj | |
| 查看仓库状态 | |
| 描述当前变更 | |
| 开启新任务 | |
| 基于指定变更创建分支 | |
| 编辑历史变更 | |
| 丢弃变更 | |
| 拆分变更 | |
| 撤销任意操作 | |
| 拉取远程代码 | |
| 追踪远程分支 | |
| 变基到 master 分支 | |
| 创建用于推送的书签 | |
| 移动已有书签 | |
| 推送到远程仓库 | |
| 推送指定书签 | |
| 推送书签删除操作 | |
| 合并多个变更 | |
| 创建并行工作区 | |
Beyond This Skill
拓展学习
This skill covers the most common operations. For advanced usage not covered here, use:
bash
jj help # List all commands
jj help <command> # Detailed help for a specific command
jj help -k <keyword> # Search help by keywordjj has rich functionality (revsets, templates, custom aliases, conflict resolution, etc.) that you can explore via and apply based on the situation. The official documentation is at https://jj-vcs.github.io/jj/.
jj help本技能覆盖了最常用的操作。对于未涵盖的高级用法,请使用以下命令查询:
bash
jj help # 列出所有命令
jj help <command> # 查看指定命令的详细帮助
jj help -k <keyword> # 按关键词搜索帮助内容jj 拥有丰富的功能(变更集、模板、自定义别名、冲突解决等),你可以通过 探索并根据实际场景使用。官方文档地址为:https://jj-vcs.github.io/jj/。
jj help