difftastic

> difftastic — 一个基于语法树的diff工具,解决传统diff看不懂代码结构变动的问题。 如果你写过代码、改过代码、review过代码,那大概率对 `git diff` 的输出又爱又恨。它能告诉你哪一行变了,但经常是一堆红色绿色糊在一起,尤其是重构、格式化、或者改了个括号缩进之后,diff输出完全没法看——满屏的“删了整段,又加回整段”,你以为改了逻辑,结果只是格式变了。 **difftastic** 就是来干这个的。它不是一个“更好看的diff”,而是一个**懂语法**的diff工具。它会把两边代码解析成抽象语法树(AST),然后在树结构上做对比。所以它能告诉你:**函数签名没变,只是里面加了一行;或者这个if条件改了,但else分支完全没动**。而不是像传统diff那样,把整个函数体标红又标绿。 它支持的语言非常多——Rust、Python、JavaScript、TypeScript、Go、Ruby、Java、C、C++、C#、Kotlin、Swift、Elixir、Clojure、Haskell、Shell、JSON、TOML、YAML……基本覆盖了主流语言和配置文件格式。而且它还能对比图片(是的,图片),甚至对比CSV表格。不过最核心的场景还是代码。 --- ### 下载方式 直接去官网:[https://difftastic.wilfred.me.uk/](https://difftastic.wilfred.me.uk/) 或者去GitHub看Release:[https://github.com/Wilfred/difftastic/releases](https://github.com/Wilfred/difftastic/releases) --- ### 安装方法 **macOS(Homebrew)** ```bash brew install difftastic ``` **Linux(apt / dnf / pacman)** Ubuntu/Debian 用户可以直接用 `cargo` 安装(见下面),或者从GitHub下载预编译的二进制。 Arch Linux 用户: ```bash sudo pacman -S difftastic ``` **Windows(Scoop / Chocolatey / 手动)** ```bash scoop install difftastic # 或者 choco install difftastic ``` **通用方法(Rust工具链)** 如果你有 `cargo`(Rust的包管理器),一条命令搞定: ```bash cargo install difftastic ``` 安装完验证一下: ```bash difft --version ``` --- ### 基础使用教程 #### 1. 直接对比两个文件 ```bash difft file1.py file2.py ``` 输出是终端彩色高亮,左边是旧文件,右边是新文件。但和传统diff不一样的是——它会把代码块按语法结构对齐。比如你改了一个函数里的某一行,它不会把整个函数都标红,而是只高亮那行变化,其他行保持绿色(表示没变)。 #### 2. 对比两个目录 ```bash difft dir1/ dir2/ ``` 它会递归对比目录下所有文件,只输出有差异的文件。这个在对比两版项目代码时非常有用。 #### 3. 作为Git的diff工具 这是最常用的姿势。先配置Git: ```bash git config --global diff.external difft ``` 或者更推荐的方式(不覆盖git diff,而是作为一个独立命令): ```bash git config --global alias.dft 'difft' ``` 然后你就可以用 `git dft` 来对比暂存区和工作区的差异了。 如果想对比两个commit: ```bash difft HEAD~1 HEAD ``` #### 4. 对比字符串或管道输入 ```bash echo "foo" | difft - <(echo "bar") ``` 或者对比两个命令的输出: ```bash difft <(cat old.json) <(cat new.json) ``` #### 5. 对比图片 ```bash difft old.png new.png ``` 它会输出图片的像素差异信息(基于像素级对比),不是视觉化图片,但能告诉你哪些区域变了。 --- ### 进阶技巧 #### 1. 自定义颜色主题 difftastic支持 `--color` 参数,但更推荐写配置文件。 在 `~/.config/difftastic/config.toml` 里(或者 `~/.difftastic.toml`)配置: ```toml [display] # 背景模式:dark, light, ansi background = "dark" # 颜色方案 color-scheme = "Nord" # 是否显示行号 line-numbers = true # 上下文行数(默认2) context = 3 # 是否显示文件的完整路径 show-path = true ``` #### 2. 忽略空白差异 有些项目有格式化规范,但你可能只想看逻辑变化: ```bash difft --ignore-whitespace old.py new.py ``` #### 3. 只显示修改行,不显示上下文 ```bash difft --context 0 file1 file2 ``` 这在对比大文件时能减少输出量。 #### 4. 和git diff一起用(不覆盖git diff) 如果你不想把difftastic设为默认diff工具,可以写个脚本或者alias: ```bash # 在 .bashrc 或 .zshrc 里 alias gdft='git diff --no-ext-difft && difft' ``` 或者用Git的 `difftool` 机制: ```bash git config --global diff.tool difftastic git config --global difftool.difftastic.cmd 'difft "$LOCAL" "$REMOTE"' ``` 然后 `git difftool` 就会调用difftastic。 #### 5. 对比JSON时保留结构 difftastic对JSON支持很好,会按键值对结构对比,而不是按行。比如两个JSON文件只有某个字段值变了,它不会把整个对象标红,而是精确到那个字段。 #### 6. 输出HTML报告 虽然difftastic本身不支持导出HTML,但你可以结合 `aha`(终端转HTML工具)实现: ```bash difft file1 file2 | aha > diff.html ``` 然后就能在浏览器里看彩色diff了。 --- ### 什么时候用difftastic,什么时候不用? **适合用**: - 代码重构(比如函数重命名、提取公共逻辑) - 格式化代码后对比(比如Prettier、Black、rustfmt跑过之后) - 对比两个版本的项目目录 - 对比JSON/TOML/YAML配置文件 **不太适合**: - 超大文件(几十万行,解析AST会慢) - 纯文本日志或自然语言(比如小说、Markdown文章,语法树意义不大) - 二进制文件(除了图片,其他不支持) --- ### 最后说两句 difftastic 不是万能药,但它确实解决了一个很痛的场景:**当代码结构变化时,传统diff的输出简直是灾难**。我自从用上它,code review的效率至少提升了30%——因为我能一眼看出“哦,这个人只是把函数换了个位置,逻辑没改”,而不是一行一行去对比红色和绿色。 如果你还没试过,建议先在几个小项目上体验一下。配置好git alias后,它就变成了一个“用了就回不去”的工具。毕竟,程序员的时间不应该浪费在解读diff上。