代码越多,Diff 越难审?OmniDiff 用语法感知视图找出真正改动
AI 编程工具提高了代码产量,却也让审查变得更费眼:一次重构可能移动了函数、替换了表达式,还顺手改变了缩进。传统的逐行 diff 往往把整段代码标成删除和新增,审查者很难快速分辨“代码真的变了多少”。
最近在 Hacker News 上出现的 CodeDiff,仓库当前名称是 OmniDiff。它是一个用 Rust 编写的语法感知差异工具:在能解析的文件上使用 Tree-sitter 识别结构变化,解析不了时回退到改进版 Myers 行级 diff。项目 README 当前列出 24 种可解析语言,并保留纯文本和二进制回退路径,适合接入 Git、代码审查和 AI Agent 生成代码后的复核流程。
它和普通 diff 的差别在哪里
普通 diff 关心的是哪几行被删除、哪几行被插入;OmniDiff 尝试进一步回答:这是移动、更新,还是仅仅换了写法?在项目展示的 Python 重构示例中,传统 diff 可能把整条赋值语句标成删除与新增,而语法感知视图只突出表达式真正变化的部分,并标记代码移动。
这类视图对 AI 生成代码尤其有用。Agent 经常会重新排版、抽取函数或调整局部结构,审查者需要关注行为变化,而不是被大量格式噪声淹没。OmniDiff 的 JSON 模式还会输出 delete、insert、update 和 move 等操作,以及每一侧文件中的范围,编辑器或自动化审查器可以据此绘制自己的高亮层。
项目作者在 HN 帖子中给出了一组基准结果:在 Gentoo 软件包列表中的约 7400 个仓库、最近 50 次提交组成的测试范围内,工具声称能在 120 秒和 6GB 内存条件下处理 99.95% 的文件对;中位数耗时为 7ms,93% 的文件低于 100ms。这些数字来自作者自己的测试,不应当当作所有机器和代码库上的保证,但足以说明它的目标不是只做演示,而是服务于批量审查。
安装和第一次运行
OmniDiff 提供源码安装、预编译包、Homebrew、Debian/Ubuntu、Nix 等方式。Rust 用户可以直接执行:
cargo install --locked omnidiff
也可以从 GitHub Release 下载适合 Linux、macOS 或 Windows 的构建产物。最简单的交互式用法是比较两个文件:
omnidiff BEFORE AFTER
如果只需要在 CI 或脚本中输出文本,不希望启动全屏界面,可以使用无头模式:
omnidiff --headless BEFORE AFTER
它也支持 --batch 作为同义选项。默认情况下,输出中的每一行带有行号,并保留变更两侧的上下文;--context N 可以调整上下文行数。对于脚本化质量门禁,--exit-code 会在文件存在差异时返回 1,而不是把“有差异”误判为工具失败。
接入 Git 和编辑器
OmniDiff 可以作为 Git difftool 使用。项目提供交互式配置向导:
omnidiff git configure git difftool --tool=omnidiff
如果团队使用 Jujutsu,也有对应的配置向导:
omnidiff jj configure
需要注意,git difftool 适合打开交互式 TUI,而 git diff 和 git log -p 会走非交互式文本输出。通过 GIT_EXTERNAL_DIFF=omnidiff git diff 可以让 Git 使用 OmniDiff 的外部 diff 接口,但这时不应期待全屏查看器。
项目还提供 VS Code、Open VSX 和 Neovim 集成。编辑器插件并不只是“把终端搬进侧栏”:README 明确说明 JSON 输出是扩展使用的基础,每个 hunk 都带有操作类型、范围和语言信息,便于编辑器将结构化结果映射回缓冲区。
放进 AI Agent 的审核环节
OmniDiff 本身不是代码生成 Agent,也不会替代测试。更合理的组合是:Agent 完成功能后,先生成补丁,再用 OmniDiff 做结构化审查;随后运行测试、静态检查和安全扫描。对于需要人工确认的变更,可以把 JSON 输出保存为审查工件,让审查界面展示移动代码、函数上下文和实际表达式变化。
使用时有三个实践建议:第一,先在团队常用语言上验证解析效果,未知扩展名会回退为逐行文本;第二,不要把 README 中的基准数字直接写成自己的性能承诺;第三,AGPL-3.0 是项目当前声明的许可证,企业接入前应让法务确认分发和修改义务。
当 AI 让“写代码”越来越便宜时,“看懂改了什么”反而成为瓶颈。OmniDiff 的价值不在于把 diff 做得更花哨,而是尽量把审查视线从行号变化拉回语法结构和行为线索。