 Git 命令对照表:从 Git 平滑迁移的完整命令速查与源码级实战解析)
Jujutsu (jj) Git 命令对照表从 Git 平滑迁移的完整命令速查与源码级实战解析【免费下载链接】jjA Git-compatible VCS that is both simple and powerful项目地址: https://gitcode.com/GitHub_Trending/jj/jjJujutsujj是一个与 Git 兼容的版本控制系统其绝大多数命令都沿用了 Git 用户熟悉的语义但底层模型更简洁、更强大。本文以官方文档中的 Git 命令对照表web/docs/src/content/docs/git-command-table.yml为骨架逐项给出 Git 与jj的等价命令并结合仓库源码说明每个命令的实际行为与适用场景。读完本文你将掌握从git迁移到jj的完整命令映射能够直接用jj完成日常开发中的仓库管理、差异查看、历史改写、分支/标签操作与撤销恢复。一、对照表的使用前提在开始逐条对照之前需要先理解 Jujutsu 与 Git 在模型上的一个关键差异Git 的大多数操作只作用于当前分支/工作副本而jj的所有命令都可以作用于任意 commitrevision。对照表为了简洁省略了这一点但它是理解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{filegit-command-table.yml}指令引用数据文件数据文件web/docs/src/content/docs/git-command-table.ymlmkdocs 版为 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 namejj git push --bookmark bookmark name [--remote remote]暂不支持推送到非 Git 仓库添加远程目标git remote add remote urljj git remote add remote url—查看状态摘要git statusjj st—查看当前变更的差异git diff HEADjj diff—查看某个变更的差异git diff revision^ revisionjj diff -r revision—查看某变更到当前变更的差异git diff revisionjj 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 revisionjj 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 的提交pickaxegit log -G stuffjj log -r diff_lines(regex:stuff)旧版diff_contains()已废弃见下文源码说明列出工作副本中已版本化的文件git ls-files --cachedjj file list—在版本化文件中搜索git grep foojj file search --patternfoo或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 --fixupreword: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 bookmarkjj 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 --fixupX; 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 sourcejj duplicate source -o destination—查找工作副本根或判断是否在仓库内git rev-parse --show-topleveljj workspace root—列出书签/分支git branchjj bookmark list或jj b l—创建书签/分支git branch name revisionjj bookmark create name -r revision—向前移动书签/分支git branch -f name revisionjj bookmark move name --to revision或jj b m name -t revision—向后或侧移书签/分支git branch -f name revisionjj bookmark move name --to revision --allow-backwards—删除书签/分支git branch --delete namejj bookmark delete name—列出标签git tag -ljj tag list—创建标签git tag name revisionjj tag set name -r revision—删除标签git tag -d namejj tag delete name—列出包含某 revision 的标签git tag --contains revisionjj tag list -r revision::::后缀运算符选择全部后代列出已并入某 revision 的标签git tag --merged revisionjj tag list -r ::revision::前缀运算符选择全部祖先查看仓库操作日志Git 不支持jj op log—撤销上一次操作Git 不支持jj undo另有对应的jj redo回滚某个历史操作Git 不支持jj op revert—创建抵消某提交的提交git revert revisionjj revert -r revision -B —查看每行最后修改的 revision 与作者git blame filejj file annotate path—三、仓库创建、克隆与远程协作3.1 初始化与克隆jj git init默认会创建一个与.git目录共存的colocated仓库让你可以随时用 Git 命令访问同一份仓库内容若想生成纯jj仓库可加--no-colocate。克隆时jj git clone source destination [--remote remote name]与 Git 的参数几乎一一对应唯一区别是远程名称参数用--remoteGit 用--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(remoteremote)..的已跟踪书签与标签--bookmark/--tag推送指定的书签或标签--all推送全部书签和标签--change则根据指定提交的 change ID 自动生成书签名。此外push 还支持--deleted以删除远程上的书签/标签。需要注意jj git push --all只影响被跟踪的书签tracked bookmarks。新克隆仓库中的书签是否出现在jj log中取决于是否执行了jj bookmark track nameremote对照表 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 revisionA 到 B 的差异jj diff --from A --to BA..B 范围内所有变更jj diff -r A..Bjj 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 logpickaxe 搜索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 --patternfoo逐行追溯jj file annotate pathjj 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 XGit 无法直接修改任意历史提交的描述需要 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 与 arrange8.1 Rebase 三兄弟需求Git 命令jj 命令把书签 A 及其分支移到 B 上git rebase B Ajj rebase -b A -o B把变更 A 及其全部后代移到 B 上git rebase --onto B A^ bookmarkjj 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-bbranch只移动书签指向的提交-ssource则连后代一起移动-rrevision精确到单个提交并用--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 --fixupX; 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 squashjj 的操作从不会中断——冲突会被记录在提交内部并继续执行之后你随时可以解决冲突并继续。这意味着写一半的 rebase不再存在也就根本没有--continue这个动作。冲突的详细处理方式参见 docs/conflicts.md。十、操作日志undo、redo 与 op revertJujutsu 的每次命令都会产生一条操作记录构成一棵操作日志树。Git 没有与之对应的概念需求jj 命令查看操作日志jj op log撤销上一次操作jj undo配套jj redo回滚某个历史操作jj op revertjj undo撤销最近一次操作jj redo重做被撤销的操作jj op revert则可以把仓库状态回滚到操作日志中任意一个操作之后的状态。配合jj abandon、jj restore等命令几乎所有手滑操作都可以无损找回这是 Git 无法提供的安全网。操作日志的原理与并发模型见 docs/technical/concurrency.md。十一、jj 独有、Git 无法直接做到的能力从对照表中可以提炼出 jj 相对 Git 的差异化能力这些能力全部源于变更change是一等公民、所有命令可作用于任意 commit的模型任意提交的描述修改jj describe XGit 需要 fixup autosquash 组合任意提交的拆分与差异编辑jj split -r revision、jj diffedit -r revisionGit 只能借助rebase -i的 edit 动作间接模拟任意变更之间的部分差异搬移jj squash -i --from X --into YGit 完全没有对应操作操作日志与全量撤销jj op log/jj undo/jj op redo/jj op revertGit 的 reflog 只覆盖引用变更且不构成完整操作历史无需 stash 的上下文切换jj new创建新变更后旧变更仍保留随时可jj edit返回。Git 与 jj 的更多理念对比可参考 docs/git-comparison.md 与 docs/git-compatibility.md。十二、延伸阅读完整 CLI 参考cli/docs/cli-reference.mdweb 版为 web/docs/src/content/docs/cli-reference.mdrevset 表达式语言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),仅供参考