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上。