Files
team/team/jj.md
T
2026-04-19 21:47:08 +08:00

10 KiB
Raw Blame History

Jujutsu (jj) 操作指南

Git 兼容的下一代版本控制系统,Rust 编写,Google 内部使用。

核心概念差异

工作副本即提交

Git 中:工作目录 → 暂存区 → 提交jj 中:工作目录就是提交

  • git add,所有变更自动跟踪
  • @ 表示当前工作副本,@- 表示父提交
  • 无"暂存区"概念,用 jj split 拆分、jj squash -i 部分合并

变更标识 vs 提交标识

标识 说明
变更标识(Change ID 逻辑变更标识,修改/变基后不变
提交标识(Commit ID 具体提交哈希,重写后改变

jj log 同时显示两者:qpvuntsm 23036a08 功能: 添加认证

操作日志(万能撤销)

记录所有操作,比 Git 的 reflog 更强大:

jj op log           # 查看操作历史
jj undo             # 撤销上一步操作(任何操作)
jj redo             # 重做
jj op restore <id>  # 恢复到指定操作状态

冲突是一等公民

冲突不会阻塞操作(变基/合并不需要 --continue),可以提交带冲突的内容,稍后解决。

版本集查询(Revset)语法

类似 SQL 的提交查询语言:

jj log -r ::@                       # @ 的所有祖先
jj log -r 'remote_bookmarks()..'    # 尚未推送的提交
jj log -r 'main..'                  # main 之后的提交
jj log -r 'mine() ~ ::immutable()'  # 我的非不可变提交

命令对照表

仓库操作

场景 Git jj 备注
初始化 git init jj git init 默认并存模式
克隆 git clone <url> jj git clone <url>
添加远程 git remote add jj git remote add

查看状态

场景 Git jj
状态 git status jj st
差异 git diff jj diff
某提交差异 git diff A^ A jj diff -r A
查看提交 git show <rev> jj show <rev>
日志 git log --graph jj log
所有日志 git log --all --graph jj log -r 'all()'

提交

场景 Git jj
暂存全部 git add . 不需要(自动跟踪)
提交 git commit -m "msg" jj describe -m "msg" && jj newjj commit -m "msg"
修改消息 git commit --amend jj describe
修改内容 git add . && git commit --amend jj squash
交互式修改 git add -p && git commit --amend jj squash -i

书签(Bookmark

场景 Git jj
列出 git branch jj bookmark list / jj b l
创建 git branch <name> jj bookmark create <name> / jj b c <name>
移动 git branch -f <name> <rev> jj bookmark move <name> --to <rev> / jj b m <name> -t @
删除 git branch -d <name> jj bookmark delete <name>

jj 中分支叫书签(bookmark),不会随提交自动移动,需手动更新。

切换与编辑

场景 Git jj
切换分支 git switch <name> jj new <name>
编辑旧提交 git rebase -i (选 edit) jj edit <rev>(直接编辑)
完成编辑 git rebase --continue jj new(新建工作副本)

历史改写

场景 Git jj
变基 git rebase main jj rebase -d main
变基指定提交 git rebase --onto B A jj rebase -s A -d B
摘选 git cherry-pick <rev> jj duplicate <rev>
拆分提交 git reset HEAD~ && git add -p ... jj split
排序提交 git rebase -i jj arrangeTUI
放弃提交 需变基 jj abandon
还原提交 git revert <rev> jj revert -r <rev>

远程操作

场景 Git jj
拉取 git pull jj git fetch + jj rebase -r @ -d trunk
推送 git push jj git push
推送指定分支 git push origin <name> jj git push -b <name>
强制推送 git push --force jj git push(默认 force-with-lease

撤销与恢复

场景 Git jj
撤销操作 无通用方法 jj undo
操作历史 git reflog jj op log
恢复工作副本 git checkout . jj restore
暂存 git stash jj new @-(创建兄弟提交)

典型工作流

日常开发

jj new main                 # 在 main 上新建工作副本
# ... 编写代码 ...
jj diff                     # 查看变更
jj describe -m "功能: xxx"  # 设置提交消息
jj new                      # 创建下一个提交(当前提交固化)

修改上一个提交

jj edit @-                  # 切换到父提交编辑
# ... 修改 ...
jj new                      # 回到新的工作副本

或用合并命令:

# 在工作副本修改后
jj squash                   # 合并到父提交

功能分支推送

jj new main
# ... 开发 ...
jj describe -m "功能: xxx"
jj b c feature-xxx          # 创建书签
jj git push -b feature-xxx  # 推送

同步远程更新

jj git fetch
jj rebase -d main           # 变基到最新 main
jj git push                 # 推送

远程同步与故障排除

同步远程更新(推荐流程)

jj git fetch                        # 拉取远程变更
jj rebase -r @ -d trunk             # 将工作区变基到最新 trunk

已配置 remotes.origin.auto-track-bookmarks = '*'fetch 后本地书签自动跟随远程。

书签跟踪状态诊断

jj bookmark list --all              # 查看所有书签及远程跟踪状态
# 输出示例:
#   trunk: <local> (commit_id)
#     @origin: <remote> (commit_id)   ← 远程跟踪版本
#     @git: <git> (commit_id)         ← git 层面版本

# 交叉验证(用 git 层面确认是否真的同步)
git log --oneline HEAD..origin/trunk

Divergent Change ID

当同一个 Change ID 对应多个提交时,jj log 会显示 (divergent) 标记。

常见原因

  • 另一个会话/工具(如 VS Code jj 扩展、直接 git 操作)对同一变更进行了重写
  • 多个 jj 操作并发执行导致操作日志分歧

排查步骤

# 1. 查看操作日志,找到分歧产生的时间点
jj op log --limit 10

# 2. 确认书签指向是否正确
jj bookmark list --tracked

# 3. 如果书签指向正确(与远程一致),只需清理分歧
#    方法 A: 回退到分歧前的操作状态(推荐)
jj op restore <操作ID>

#    方法 B: 放弃不需要的 divergent 版本(注意:如果它是另一个版本的祖先会引发冲突)
jj abandon <divergent版本> --ignore-immutable

注意事项

  • 不要轻易 jj abandon 一个 divergent 版本,如果它是另一个版本的祖先(parent),会产生大量冲突
  • 优先使用 jj op restore 回退到分歧前的干净状态
  • divergent 标记只影响 jj 内部的 Change ID 映射,不影响实际提交数据

fetch 返回 "Nothing changed" 但远程有新提交

排查清单

  1. 检查 @origin 跟踪是否已更新(可能其他进程/扩展已 fetch 过)
  2. git fetch origin && git log HEAD..origin/trunk 交叉验证
  3. 检查是否是 divergent 状态导致工作区 parent 不在最新 trunk 上

关键配置

# 用户级配置文件
jj config path --user   # → ~/.config/jj/config.toml

# 自动跟踪远程书签(替代已废弃的 git.auto-local-bookmark
jj config set --user 'remotes.origin.auto-track-bookmarks' "'*'"

# 查看所有配置(含默认值)
jj config list git --include-defaults
配置项 推荐值 说明
remotes.origin.auto-track-bookmarks '*' fetch 后本地书签自动跟随远程
git.push-new-bookmarks false 防止意外推送新书签

Workspace(多工作副本)

jj 原生支持多工作副本,概念上等同于 git worktree,但融入 jj 的变更模型。

命令对照

场景 Git jj
创建工作副本 git worktree add <path> <branch> jj workspace add [-r <rev>] <path>
列出工作副本 git worktree list jj workspace list
删除工作副本 git worktree remove <path> jj workspace forget <name>

日常使用

# 为功能分支创建独立工作目录
jj workspace add -r trunk ../feature-a
jj workspace add -r trunk ../feature-b

# 在各目录独立工作
cd ../feature-a
# ... 编辑代码 ...
jj describe -m "功能: 实现认证"
jj new

# 回到主目录查看
cd ../my-project
jj workspace list

每个 workspace 拥有独立的 .jj/ 目录和自己的 @ 工作副本,共享同一个底层仓库。

Claude Code Agent 并行开发

Claude Code 的 EnterWorktree 工具内部调用 git worktree add(不是 jj workspace),在 jj 并存模式下两种路径对比:

路径 方式 兼容性 说明
Claude Code EnterWorktree git worktree 可用 git 层面隔离,jj 需 jj git import 同步
手动 jj workspace add jj workspace jj 原生 jj 完全感知,但 Agent 无法自动调用

推荐方案Agent 并行开发使用 Claude Code 内置 EnterWorktree

Agent-1: EnterWorktree → .claude/worktrees/xxx/ (git worktree)
Agent-2: EnterWorktree → .claude/worktrees/yyy/ (git worktree)
主目录:  jj 管理 trunk

Agent 在 worktree 中完成工作后,主目录同步:

jj git fetch
jj git import    # 将 Agent 的 git worktree 提交导入 jj 视图

注意git worktree 创建的目录没有 .jjjj 不主动跟踪这些 worktree。通过 jj git import 可将 git 层面的变更同步到 jj 视图。

注意事项

与 Git 共存

并存模式下 .jj.git 并存,两边可互操作:

jj git import   # 将 git 变更导入 jj
jj git export   # 将 jj 变更导出到 git

IDE 集成

  • VS Code 有 jj 扩展但功能不如 GitLens 成熟
  • 部分工具只识别 git,可能需要 jj git export
  • JetBrains 插件开发中

性能

  • 大仓库可能因 Git 导入/导出开销稍慢
  • 普通仓库无感知差异

安装

# macOS
brew install jj

# Linux (Cargo)
cargo install --locked --bin jj jj-cli

# Linux (Arch)
pacman -S jujutsu

# Windows
winget install jj-vcs.jj

参考资源


最后更新: 2026-04-14