☰
Jujutsu (jj) Git 命令对照表:从 Git 平滑迁移的完整命令速查与源码级实战解析
2026/10/12 16:06:20 网站建设 项目流程

Jujutsu (jj) Git 命令对照表:从 Git 平滑迁移的完整命令速查与源码级实战解析

【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj

Jujutsu(jj)是一个与 Git 兼容的版本控制系统,其绝大多数命令都沿用了 Git 用户熟悉的语义,但底层模型更简洁、更强大。本文以官方文档中的 Git 命令对照表(web/docs/src/content/docs/git-command-table.yml)为骨架,逐项给出 Git 与jj的等价命令,并结合仓库源码说明每个命令的实际行为与适用场景。读完本文,你将掌握从git迁移到jj的完整命令映射,能够直接用jj完成日常开发中的仓库管理、差异查看、历史改写、分支/标签操作与撤销恢复。

一、对照表的使用前提

在开始逐条对照之前,需要先理解 Jujutsu 与 Git 在模型上的一个关键差异:Git 的大多数操作只作用于"当前分支/工作副本",而jj的所有命令都可以作用于任意 commit(revision)。对照表为了简洁省略了这一点,但它是理解jj能力的基础。

例如,Git 中只能git commit --amend修改当前提交,而 Jujutsu 中:

jj squash -r <revision>

会将指定 revision 的 diff 移入其 parent——即使该 revision 并不是工作副本提交。这种"任意 revision 可寻址、可改写"的设计,正是jj历史改写如此轻松的根本原因。

本文的对照表数据以仓库中的 YAML 文件为唯一事实来源(web 站点版与 mkdocs 版各有一份,内容基本一致,本文合并了两者并采用当前源码确认的命令形式):

  • 渲染入口:web/docs/src/content/docs/git-command-table.md 通过::yaml-table{file="git-command-table.yml"}指令引用数据文件;
  • 数据文件:web/docs/src/content/docs/git-command-table.yml(mkdocs 版为 docs/git-command-table.yml);
  • 渲染插件:web/docs/plugins/remark-yaml-table.mjs 将 YAML 数组解析为 Markdown 表格,每个对象一行、键名作为列头。

二、Git → jj 完整命令对照总表

下表覆盖官方文档的全部条目(使用场景、Git 命令、jj 命令、备注)。@表示当前工作副本提交,@-表示其父提交;revset 语法详见 docs/revsets.md。

使用场景Git 命令jj 命令备注
创建新仓库git initjj git init [--no-colocate]默认创建与.git共存的 colocated 仓库
克隆已有仓库git clone <source> <destination> [--origin <remote name>]jj git clone <source> <destination> [--remote <remote name>]暂不支持克隆非 Git 仓库
从远程拉取所有分支git fetch [<remote>]jj git fetch [--remote <remote>]暂不支持从非 Git 仓库拉取
推送所有分支到远程git push --all [<remote>]jj git push --all [--remote <remote>]只影响被跟踪的书签(bookmark)
推送单个分支到远程git push <remote> <bookmark name>jj git push --bookmark <bookmark name> [--remote <remote>]暂不支持推送到非 Git 仓库
添加远程目标git remote add <remote> <url>jj git remote add <remote> <url>—
查看状态摘要git statusjj st—
查看当前变更的差异git diff HEADjj diff—
查看某个变更的差异git diff <revision>^ <revision>jj diff -r <revision>—
查看某变更到当前变更的差异git diff <revision>jj diff --from <revision>—
查看变更 A 到变更 B 的差异git diff A Bjj diff --from A --to B—
查看 A..B 范围内所有变更git diff A...Bjj diff -r A..Brevset 范围语法
查看变更描述与差异git show <revision>jj show <revision>—
添加文件到当前变更touch filename; git add filenametouch filenamejj 自动快照工作副本
从当前变更移除文件git rm filenamerm filename—
取消跟踪但仍保留在磁盘git rm --cached filenamejj file untrack filename文件名必须匹配 ignore 模式才能保持未跟踪,见工作副本文档
修改当前变更中的文件echo stuff >> filenameecho stuff >> filename—
完成当前变更并开始新变更git commit -ajj commit—
查看当前提交祖先的紧凑日志git log --oneline --graphjj log -r ::@::@表示 @ 的所有祖先
查看所有可达提交的紧凑日志git log --oneline --graph --alljj log -r 'all()'或jj log -r ::Git 会显示 jj 保留的隐藏提交,可用--exclude refs/jj/* --all排除
查看 main 分支之外的提交git log --oneline --graph --branches --not upstream/mainjj log—
查找变更行包含 "stuff" 的提交(pickaxe)git log -G stuffjj log -r 'diff_lines(regex:stuff)'旧版diff_contains()已废弃,见下文源码说明
列出工作副本中已版本化的文件git ls-files --cachedjj file list—
在版本化文件中搜索git grep foojj file search --pattern=foo或rg --no-require-git foo—
放弃当前变更并开始新变更git reset --hard(不可撤销)jj abandon—
将当前变更清空git reset --hardjj restore—
放弃工作副本的父提交但保留其差异git reset --soft HEAD~jj squash --from @-—
丢弃部分文件的工作副本改动git restore <paths>...或git checkout HEAD -- <paths>...jj restore <paths>...—
修改当前变更描述Git 不支持jj describe—
修改上一个变更的描述git commit --amend --onlyjj describe @-—
修改任意变更的描述git commit --fixup=reword:X; git rebase --autosquash X^jj describe X—
暂时收起当前变更git stashjj new @-旧工作副本提交保留为兄弟提交,可用jj edit X恢复
基于 main 书签开始新变更git switch -c topic main或git checkout -b topic mainjj new main无需先 stash 或 commit
将分支 A 合并进当前变更git merge Ajj new @ A创建合并提交
检出命名 revision 以查看源码git checkout v1.0.1jj new v1.0.1在其上创建新空变更
将书签 A 移到书签 B 上git rebase B Ajj rebase -b A -o B—
将变更 A 及其后代移到 B 上git rebase --onto B A^ <some descendant bookmark>jj rebase -s A -o B—
将变更顺序 A-B-C-D 重排为 A-C-B-Dgit rebase -i Ajj rebase -r C --before B—
一次重排多个提交git rebase -ijj arrange交互式重排
将当前变更的差异并入父变更git commit --amend -ajj squash—
交互式将部分差异并入父变更git add -p; git commit --amendjj squash -i—
将工作副本差异并入某个祖先git commit --fixup=X; git rebase --autosquash X^jj squash --into X—
交互式把任意变更的部分差异移到另一变更Git 不支持jj squash -i --from X --into Y—
交互式把工作副本变更一分为二git commit -pjj split—
交互式把任意变更一分为二Git 不支持(可用git rebase -i的 edit 模拟)jj split -r <revision>—
交互式编辑某变更的差异Git 不支持(可用 edit 模拟)jj diffedit -r <revision>—
解决冲突并继续中断的操作echo resolved > filename; git add filename; git rebase/merge/cherry-pick --continueecho resolved > filename; jj squash操作不会中断,无需 continue
在另一提交之上创建提交副本git co <destination>; git cherry-pick <source>jj duplicate <source> -o <destination>—
查找工作副本根(或判断是否在仓库内)git rev-parse --show-topleveljj workspace root—
列出书签/分支git branchjj bookmark list或jj b l—
创建书签/分支git branch <name> <revision>jj bookmark create <name> -r <revision>—
向前移动书签/分支git branch -f <name> <revision>jj bookmark move <name> --to <revision>或jj b m <name> -t <revision>—
向后或侧移书签/分支git branch -f <name> <revision>jj bookmark move <name> --to <revision> --allow-backwards—
删除书签/分支git branch --delete <name>jj bookmark delete <name>—
列出标签git tag -ljj tag list—
创建标签git tag <name> <revision>jj tag set <name> -r <revision>—
删除标签git tag -d <name>jj tag delete <name>—
列出包含某 revision 的标签git tag --contains <revision>jj tag list -r '<revision>::'::后缀运算符选择全部后代
列出已并入某 revision 的标签git tag --merged <revision>jj tag list -r '::<revision>'::前缀运算符选择全部祖先
查看仓库操作日志Git 不支持jj op log—
撤销上一次操作Git 不支持jj undo另有对应的jj redo
回滚某个历史操作Git 不支持jj op revert—
创建抵消某提交的提交git revert <revision>jj revert -r <revision> -B @—
查看每行最后修改的 revision 与作者git blame <file>jj file annotate <path>—

三、仓库创建、克隆与远程协作

3.1 初始化与克隆

jj git init默认会创建一个与.git目录共存的colocated仓库,让你可以随时用 Git 命令访问同一份仓库内容;若想生成纯jj仓库,可加--no-colocate。

克隆时,jj git clone <source> <destination> [--remote <remote name>]与 Git 的参数几乎一一对应,唯一区别是远程名称参数用--remote(Git 用--origin)。文档明确标注:目前 jj 只支持克隆/拉取/推送 Git 仓库,非 Git 仓库的互操作尚不支持。

3.2 拉取与推送

jj git fetch [--remote <remote>] # 等价于 git fetch [<remote>] jj git push --all [--remote <remote>] # 等价于 git push --all [<remote>] jj git push --bookmark <name> [--remote <remote>] # 等价于 git push <remote> <name>

在源码层面,jj git push的能力比表格展示的更丰富。查看 cli/src/commands/git/push.rs,其帮助文本说明:默认推送的是指向remote_bookmarks(remote=<remote>)..@的已跟踪书签与标签;--bookmark/--tag推送指定的书签或标签,--all推送全部书签和标签,--change则根据指定提交的 change ID 自动生成书签名。此外,push 还支持--deleted以删除远程上的书签/标签。

需要注意:jj git push --all只影响被跟踪的书签(tracked bookmarks)。新克隆仓库中的书签是否出现在jj log中,取决于是否执行了jj bookmark track <name>@<remote>(对照表 YAML 中的 TODO 注释也提到了这一点)。

3.3 远程管理

jj git remote add <remote> <url>与 Git 完全等价,配套的还有jj git remote remove、jj git remote rename、jj git remote set-url、jj git remote list(见 cli/src/commands/git/remote/)。

四、查看状态、差异与历史日志

4.1 状态与差异

需求jj 命令
状态摘要jj st
当前变更的差异jj diff
某变更自身的差异jj diff -r <revision>
某变更到当前变更的差异jj diff --from <revision>
A 到 B 的差异jj diff --from A --to B
A..B 范围内所有变更jj diff -r A..B

jj diff -r A..B中的A..B是 revset 的范围语法,jj会给出从 A 到 B 的所有变更的累计差异——这比 Git 的git diff A...B(三点 diff)更符合直觉。

4.2 日志查看

需求jj 命令
当前提交祖先的日志jj log -r ::@
全部可达提交的日志jj log -r 'all()'或jj log -r ::
main 之外的分支jj log
pickaxe 搜索jj log -r 'diff_lines(regex:stuff)'

关于 pickaxe 的写法需要特别说明:官方 web 版 YAML 中写的是jj log -r 'diff_contains(stuff)',但查看 revset 实现 lib/src/revset.rs 可以发现,diff_contains()已被标记为废弃:

map.insert("diff_lines", |diagnostics, function, context| { if function.name != "diff_lines" { // TODO: Remove in jj 0.44+ diagnostics.add_warning(RevsetParseError::expression( "diff_contains() is deprecated; use diff_lines() instead", function.name_span, )); } ... }); map.insert("diff_contains", map["diff_lines"]);

也就是说,diff_contains目前仍可用(作为diff_lines的别名并发出弃用警告),但新代码应使用diff_lines。与之配套的还有diff_lines_added()与diff_lines_removed(),分别只匹配新增/删除行。

4.3 查看单条变更

jj show <revision>等价于git show <revision>,同时展示描述与差异。

五、文件的增删与内容搜索

Jujutsu 最省心的特性之一是自动快照:工作副本的任何改动都会在下次命令执行时自动记录到当前变更中,因此"添加文件"不再需要显式git add:

需求jj 命令
添加文件到当前变更touch filename(自动被跟踪)
删除文件rm filename(自动记录删除)
取消跟踪但保留文件jj file untrack filename
修改文件直接编辑
列出已版本化文件jj file list
在版本化文件中搜索jj file search --pattern=foo
逐行追溯jj file annotate <path>

jj file untrack有一个易被忽略的细节:文件名必须匹配某个 ignore 模式才能保持未跟踪,否则它仍会被工作副本快照重新纳入跟踪(详见工作副本文档)。

内容搜索推荐使用内置的jj file search(实现见 cli/src/commands/file/search.rs),它支持:

  • --revision <revset>:指定在哪个 revision 中搜索(默认@);
  • --pattern <pattern>:字符串模式,语法为kind:pattern,省略 kind 时默认按正则匹配;glob 模式下需要整行匹配,例如--pattern 'glob:*foo*';
  • --name-only:只打印包含匹配的文件路径;
  • --line-number/-n:在匹配行前加行号。

六、提交、描述信息与丢弃

6.1 提交与描述

需求jj 命令
完成当前变更并开新变更jj commit
修改当前变更描述jj describe
修改上一变更描述jj describe @-
修改任意变更描述jj describe X

Git 无法直接修改任意历史提交的描述(需要 fixup + autosquash 的组合拳),而jj describe X一行搞定——这正是"所有命令可作用于任意 commit"的体现。

6.2 丢弃与恢复

需求jj 命令
放弃当前变更jj abandon(对应git reset --hard,但可撤销)
清空当前变更jj restore
放弃父提交但保留其差异jj squash --from @-(对应git reset --soft HEAD~)
丢弃部分文件的改动jj restore <paths>...
暂时收起当前变更jj new @-

对照表中"放弃当前变更"特别标注 Git 的git reset --hard不可撤销,而jj abandon之后随时可以用jj undo找回——Jujutsu 的操作日志机制让"危险操作"不再危险。

"暂时收起"对应 Git 的git stash,但语义完全不同:jj new @-只是在你当前提交的父提交之上新建一个空变更并切换过去,原来的工作副本提交并不会消失,而是作为兄弟提交留在历史中,之后用jj edit X即可回到它继续工作。没有单独的 stash 概念,也不需要它。

七、分支(Bookmark)与标签(Tag)管理

7.1 书签即分支

Jujutsu 中与 Git 分支对应的是bookmark(书签),命令集中在 cli/src/commands/bookmark/:

需求jj 命令
列出书签jj bookmark list(简写jj b l)
创建书签jj bookmark create <name> -r <revision>
向前移动jj bookmark move <name> --to <revision>(简写jj b m <name> -t <revision>)
向后/侧移jj bookmark move <name> --to <revision> --allow-backwards
删除书签jj bookmark delete <name>

与 Git 的一个关键区别:Git 的git branch -f不允许把分支移到其自身后代之外的位置,而jj bookmark move默认也不允许向后移动,需要显式加--allow-backwards。此外还有jj bookmark set、jj bookmark rename、jj bookmark track/untrack等命令用于远程书签跟踪管理。

7.2 标签

标签命令位于 cli/src/commands/tag/(list/set/delete/track/untrack):

需求jj 命令
列出标签jj tag list
创建标签jj tag set <name> -r <revision>
删除标签jj tag delete <name>
列出包含某 revision 的标签jj tag list -r '<revision>::'
列出已并入某 revision 的标签jj tag list -r '::<revision>'

最后两条用到了 revset 的范围运算符:<revision>::后缀形式选择该 revision 的所有后代(等价于git tag --contains),::<revision>前缀形式选择其所有祖先(等价于git tag --merged)。revset 的完整语法见 docs/revsets.md。

八、历史改写:rebase、squash、split、diffedit 与 arrange

8.1 Rebase 三兄弟

需求Git 命令jj 命令
把书签 A 及其分支移到 B 上git rebase B Ajj rebase -b A -o B
把变更 A 及其全部后代移到 B 上git rebase --onto B A^ <bookmark>jj rebase -s A -o B
重排 A-B-C-D 为 A-C-B-Dgit rebase -i Ajj rebase -r C --before B
一次重排多个提交git rebase -ijj arrange

-b(branch)只移动书签指向的提交,-s(source)则连后代一起移动,-r(revision)精确到单个提交并用--before/--after指定新位置。jj arrange(实现见 cli/src/commands/arrange.rs)则提供了交互式重排多个提交的界面,替代git rebase -i的 todo 编辑。

值得强调:Git 的git rebase B A之后,A 的其他后代分支往往需要单独再 rebase 一次;而 jj 的jj rebase -b A -o B会一并移动 A 的所有后代,无需逐个处理。

8.2 Squash 与 Split

需求Git 命令jj 命令
把当前变更并入父变更git commit --amend -ajj squash
交互式并入部分差异git add -p; git commit --amendjj squash -i
并入某个祖先git commit --fixup=X; git rebase --autosquash X^jj squash --into X
任意变更之间的部分合并Git 不支持jj squash -i --from X --into Y
拆分工作副本变更git commit -pjj split
拆分任意变更Git 不支持jj split -r <revision>
编辑任意变更的差异Git 不支持jj diffedit -r <revision>

对照表开头示例中的jj squash -r <revision>也是同理:把任意指定 revision 的差异并入其父提交。

8.3 复制提交

jj duplicate <source> -o <destination>

等价于 Git 的git co <destination>; git cherry-pick <source>,但无需切换工作副本即可在任意目标上复制任意来源提交。

九、冲突处理:操作永不中断

这是 Jujutsu 相对 Git 最具颠覆性的设计之一。Git 中执行rebase/merge/cherry-pick遇到冲突会中断操作,要求你解决冲突后git add再--continue;而 jj 的处理方式是:

echo resolved > filename; jj squash

jj 的操作从不会中断——冲突会被记录在提交内部并继续执行,之后你随时可以解决冲突并继续。这意味着"写一半的 rebase"不再存在,也就根本没有--continue这个动作。冲突的详细处理方式参见 docs/conflicts.md。

十、操作日志:undo、redo 与 op revert

Jujutsu 的每次命令都会产生一条操作记录,构成一棵操作日志树。Git 没有与之对应的概念:

需求jj 命令
查看操作日志jj op log
撤销上一次操作jj undo(配套jj redo)
回滚某个历史操作jj op revert

jj undo撤销最近一次操作,jj redo重做被撤销的操作;jj op revert则可以把仓库状态回滚到操作日志中任意一个操作之后的状态。配合jj abandon、jj restore等命令,几乎所有"手滑"操作都可以无损找回,这是 Git 无法提供的安全网。操作日志的原理与并发模型见 docs/technical/concurrency.md。

十一、jj 独有、Git 无法直接做到的能力

从对照表中可以提炼出 jj 相对 Git 的差异化能力,这些能力全部源于"变更(change)是一等公民、所有命令可作用于任意 commit"的模型:

  1. 任意提交的描述修改:jj describe X,Git 需要 fixup + autosquash 组合;
  2. 任意提交的拆分与差异编辑:jj split -r <revision>、jj diffedit -r <revision>,Git 只能借助rebase -i的 edit 动作间接模拟;
  3. 任意变更之间的部分差异搬移:jj squash -i --from X --into Y,Git 完全没有对应操作;
  4. 操作日志与全量撤销:jj op log/jj undo/jj op redo/jj op revert,Git 的 reflog 只覆盖引用变更且不构成完整操作历史;
  5. 无需 stash 的上下文切换:jj new创建新变更后旧变更仍保留,随时可jj edit返回。

Git 与 jj 的更多理念对比,可参考 docs/git-comparison.md 与 docs/git-compatibility.md。

十二、延伸阅读

  • 完整 CLI 参考:cli/docs/cli-reference.md(web 版为 web/docs/src/content/docs/cli-reference.md)
  • revset 表达式语言:docs/revsets.md
  • 书签(分支)模型:docs/bookmarks.md
  • 工作副本与自动快照:docs/working-copy.md
  • 冲突表示与解决:docs/conflicts.md
  • 上手教程:docs/tutorial.md

【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jj

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询