Jujutsu(jj)是一个与 Git 兼容的版本控制系统,但采用了不同的数据模型:没有暂存区,改动即时生效。工作副本中的每个文件都以“changes”(类似没有父提交的 commit)的形式被跟踪。
重要限制:在 jj 仓库中绝不要使用 git 执行变更操作,否则会破坏历史。允许使用的 git 命令包括:git log、git diff、git show、git blame、git grep。
基本工作流
创建 change、编写描述、查看历史:
jj new # 开始一个新的 change(类似在一个 commit 上工作) jj desc -m "feat: add login" # 编写提交信息 jj log # 查看历史——这是主要的查看命令 jj diff # 查看工作副本中的改动
编辑已有的 change:
jj edit <change-id> # 切换到指定的 change
修改文件...
jj squash # 将新的编辑移入父 change
时间旅行与导航
跳转到历史中的任意位置:
jj edit @- # 前往父节点 jj next --edit # 前往子节点 jj edit <change-id> # 跳转到指定 change jj new --before @ # 在当前 change 之前插入一个新 change
压缩与拆分 change
将多个 change 合并为一个:
将两个 change 合并在一起
jj squash -m "combined message"
将工作副本拆分为多个独立提交
jj split # 交互式——选择要单独提交的代码块
自动将改动移动到栈中相关的提交:
jj absorb # 在可变修订之间进行智能压缩
变基与合并
将 change 变基到另一个 change 上:
jj rebase -s @- -d main # 将当前 change 变基到 main 上 jj rebase -d main -s ::@ # 将 @ 的所有后代变基到 main 上
合并两个 change:
jj new x yz -m "merge" # 创建 x 与 yz 的合并
冲突
交互式解决冲突:
编辑冲突文件,然后继续
jj resolve
推送到 Git
Bookmark 类似于分支。跟踪并推送它们:
jj bookmark create main -r @ # 在当前 change 处创建 bookmark jj git push --bookmark main # 推送该 bookmark jj git fetch # 从远程获取 jj bookmark track main@origin # 跟踪远程 bookmark
实用模式
撤销操作:jj undo——反转上一条 jj 命令。
从 jj change 获取 git commit 哈希:
jj log -T 'commit_id\n' -r @ # 完整哈希 jj log -T 'commit_id.short()\n' -r @ # 短哈希 git rev-parse @ # 在共置仓库中同样可用
操作历史:jj op log——查看所有 jj 操作。
常见陷阱
❌ 使用 @~1 → ✅ 使用 @-(父节点)
❌ 使用 a,b,c 表示并集 → ✅ 使用 a | b | c(竖线,而非逗号)
❌ 使用 jj changes → ✅ 使用 jj log 或 jj diff
相关技能
conventional-commits:提交信息格式
sem:在编写提交信息前进行语义分析