jj-core

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Jujutsu

Jujutsu

Git-compatible VCS with a different data model — no staging area, changes are immediate. Every file is tracked in the working copy as "changes" (like commits without parents).
⚠️ Never use
git
for mutations in a jj repo
— it corrupts history. Allowed:
git log
,
git diff
,
git show
,
git blame
,
git grep
.
一款与Git兼容的版本控制系统(VCS),采用不同的数据模型——无需暂存区,变更即时生效。工作副本中的每个文件都会被作为"变更"跟踪(类似无父提交的提交)。
⚠️ 切勿在jj仓库中使用
git
执行变更操作
——这会破坏历史记录。允许使用的命令:
git log
git diff
git show
git blame
git grep

Basic Workflow

基础工作流

Create a change, describe it, view history:
bash
jj new                   # Start a new change (like working on a commit)
jj desc -m "feat: add login"  # Write the message
jj log                   # View history — this is your main view command
jj diff                  # See what changed in working copy
Edit an existing change:
bash
jj edit <change-id>      # Switch to a specific change
创建变更、描述变更、查看历史:
bash
jj new                   # 启动一个新变更(类似开发一个提交)
jj desc -m "feat: add login"  # 编写提交信息
jj log                   # 查看历史——这是你的核心查看命令
jj diff                  # 查看工作副本中的变更
编辑已有变更:
bash
jj edit <change-id>      # 切换到指定变更

Make changes to files...

对文件进行修改...

jj squash # Move new edits into the parent change
undefined
jj squash # 将新编辑内容合并到父变更中
undefined

Time Travel & Navigation

时光回溯与导航

Jump to any point in history:
bash
jj edit @-               # Go to parent
jj next --edit           # Go to child
jj edit <change-id>      # Jump to specific change
jj new --before @        # Insert a new change before current
跳转到历史中的任意节点:
bash
jj edit @-               # 回到父变更
jj next --edit           # 切换到子变更
jj edit <change-id>      # 跳转到指定变更
jj new --before @        # 在当前变更前插入新变更

Squash & Split Changes

压缩与拆分变更

Combine changes into one:
bash
undefined
将多个变更合并为一个:
bash
undefined

Merge two changes together

合并两个变更

jj squash -m "combined message"
jj squash -m "combined message"

Split working copy into separate commits

将工作副本拆分为多个独立提交

jj split # Interactive — pick hunks to commit separately

Auto-move changes to relevant commits in a stack:

```bash
jj absorb                # Smart squashing across mutable revisions
jj split # 交互式操作——选择代码块分别提交

自动将变更移动到栈中对应的提交:

```bash
jj absorb                # 在可变版本间智能压缩变更

Rebasing & Merging

变基与合并

Rebase changes onto another:
bash
jj rebase -s @- -d main  # Rebase current change onto main
jj rebase -d main -s ::@ # Rebase all descendants of @ onto main
Merge two changes:
bash
jj new x yz -m "merge"   # Create merge of x and yz
将变更变基到另一个变更之上:
bash
jj rebase -s @- -d main  # 将当前变更变基到main分支
jj rebase -d main -s ::@ # 将当前变更的所有后代变基到main分支
合并两个变更:
bash
jj new x yz -m "merge"   # 创建x和yz的合并变更

Conflicts

冲突处理

Resolve interactively:
bash
undefined
交互式解决冲突:
bash
undefined

Edit conflicted files, then continue

编辑冲突文件,然后继续

jj resolve
undefined
jj resolve
undefined

Pushing to Git

推送到Git仓库

Bookmarks are like branches. Track and push them:
bash
jj bookmark create main -r @   # Create a bookmark at current change
jj git push --bookmark main    # Push that bookmark
jj git fetch                   # Fetch from remote
jj bookmark track main@origin  # Track a remote bookmark
书签(Bookmarks)类似分支。创建跟踪并推送书签:
bash
jj bookmark create main -r @   # 在当前变更处创建书签
jj git push --bookmark main    # 推送该书签
jj git fetch                   # 从远程仓库拉取
jj bookmark track main@origin  # 跟踪远程书签

Useful Patterns

实用模式

Undo an operation:
jj undo
— reverses the last jj command.
Get git commit hash from jj change:
bash
jj log -T 'commit_id\n' -r @           # Full hash
jj log -T 'commit_id.short()\n' -r @   # Short hash
git rev-parse @                        # Also works in colocated repos
Operation history:
jj op log
— see all jj operations.
撤销操作:
jj undo
—— 撤销上一条jj命令。
从jj变更获取Git提交哈希:
bash
jj log -T 'commit_id\n' -r @           # 完整哈希
jj log -T 'commit_id.short()\n' -r @   # 短哈希
git rev-parse @                        # 在共存仓库中同样生效
操作历史:
jj op log
—— 查看所有jj操作记录。

Template Syntax (
-T
/
--template
)

模板语法(
-T
/
--template

Templates use jj's own language — NOT JavaScript, NOT shell interpolation.
String concatenation requires
concat()
:
bash
undefined
模板使用jj自身的语言——不是JavaScript,也不是shell插值。
字符串拼接需要使用
concat()
bash
undefined

❌ WRONG — no implicit joining

❌ 错误——无隐式拼接

jj log -r @ -T 'commit_id.short() description'
jj log -r @ -T 'commit_id.short() description'

❌ WRONG — method chaining without concat

❌ 错误——无concat的方法链

jj log -r @ -T 'change_id.short() " | " commit_id.short()'
jj log -r @ -T 'change_id.short() " | " commit_id.short()'

✅ RIGHT — explicit concat

✅ 正确——显式concat

jj log -r @ -T 'concat(change_id.short(), " | ", description)'

**Common fields:** `change_id`, `commit_id`, `description`, `author`, `committer`, `signature`

**Field name is `description`, NOT `desc`:**

```bash
jj log -r @ -T 'concat(change_id.short(), " | ", description)'

**常用字段:** `change_id`、`commit_id`、`description`、`author`、`committer`、`signature`

**字段名为`description`,而非`desc`:**

```bash

❌ WRONG — undefined field

❌ 错误——字段未定义

jj log -r @ -T 'desc'
jj log -r @ -T 'desc'

✅ RIGHT

✅ 正确

jj log -r @ -T 'description'

**Double quotes for pipe alternation in bash:**

```bash
jj log -r @ -T 'description'

**bash中管道交替需使用双引号:**

```bash

✅ RIGHT — double quotes around revision set with pipe

✅ 正确——版本集使用双引号包裹管道

jj log -r "id1 | id2" -T 'concat(change_id.short(), "\n", description)'
jj log -r "id1 | id2" -T 'concat(change_id.short(), "\n", description)'

❌ WRONG — single quotes don't expand variables and can nest incorrectly

❌ 错误——单引号不会展开变量且嵌套易出错

jj log -r 'id1 | id2' -T 'description'

**After `jj desc`, the working copy (`@`) moves:**

```bash
jj log -r 'id1 | id2' -T 'description'

**执行`jj desc`后,工作副本(`@`)会移动:**

```bash

Always verify with the original change ID, not @

始终使用原始变更ID验证,而非@

jj desc -r <change-id> -m "new description" jj log --no-graph -r <change-id> -T 'concat(change_id.short(), " | ", description)'
undefined
jj desc -r <change-id> -m "new description" jj log --no-graph -r <change-id> -T 'concat(change_id.short(), " | ", description)'
undefined

Common Pitfalls

常见误区

  • ❌ Use
    @~1
    → ✅ Use
    @-
    (parent)
  • ❌ Use
    a,b,c
    for union → ✅ Use
    a | b | c
    (pipe, not comma)
  • ❌ Use
    jj changes
    → ✅ Use
    jj log
    or
    jj diff
  • ❌ Template: implicit string joining → ✅ Always use
    concat(a, b)
  • ❌ Template:
    desc
    → ✅ Always use
    description
  • ❌ Verify with
    @
    after
    jj desc
    → ✅ Always use original change ID
  • ❌ 使用
    @~1
    → ✅ 使用
    @-
    (父变更)
  • ❌ 使用
    a,b,c
    表示并集 → ✅ 使用
    a | b | c
    (管道,而非逗号)
  • ❌ 使用
    jj changes
    → ✅ 使用
    jj log
    jj diff
  • ❌ 模板:隐式字符串拼接 → ✅ 始终使用
    concat(a, b)
  • ❌ 模板:
    desc
    → ✅ 始终使用
    description
  • ❌ 执行
    jj desc
    后用
    @
    验证 → ✅ 始终使用原始变更ID