Wilfred/difftastic
GitHub: Wilfred/difftastic
基于语法树的智能 diff 工具,能精确识别代码语义变化而非机械按行比对。
Stars: 24447 | Forks: 445
Difftastic 是一款结构化的 diff 工具,它基于文件的语法进行比较。
**安装说明请参阅[手册](http://difftastic.wilfred.me.uk/)中的[安装](https://difftastic.wilfred.me.uk/installation.html)章节。**
## 示例

^ Difftastic 能精确理解语法变化的细节,并能在上下文中高亮显示它们。

^ Difftastic 知道何时空白字符是有意义的,而何时仅仅是缩进的改变。

^ Difftastic 不是面向行的。如果你重新格式化代码,使其现在被分割成多行,Difftastic 依然能准确显示实际发生的变化。

^ Difftastic 兼容 git(参见[配置说明](http://difftastic.wilfred.me.uk/git.html)),以及许多其他版本控制系统。
## 支持的语言
Difftastic 支持 30 多种编程语言,完整列表请参见[手册](https://difftastic.wilfred.me.uk/languages_supported.html)。
如果文件的扩展名无法识别,difftastic 会使用带有单词高亮的面向行的 diff。
## 已知问题
性能。在包含大量更改的文件上,Difftastic 的扩展性相对较差,并且可能会消耗大量内存。
显示。Difftastic 采用并排显示方式,这通常效果不错,但有时可能会令人困惑。
鲁棒性。Difftastic 经常发布修复崩溃的版本。
## 非目标
补丁。Difftastic 的输出旨在供人阅读,它不会生成可以稍后应用的补丁。如果你需要补丁,请使用 `diff`。
(补丁文件也是面向行的,这对 difftastic 来说太局限了。Difftastic 可能会在同一行中发现添加和删除,并且它会跟踪旧文件和新文件中行号之间的关系。)
合并。AST 合并是一个难题,difftastic 并不解决这个问题。你可能会对 [mergiraf 工具](https://mergiraf.org/)("merge giraffe")感兴趣,它确实能进行 AST 合并。
## 常见问题
### 我可以在 git 中使用 difftastic 吗?
可以!Difftastic 手册中[包含了 git 使用说明](https://difftastic.wilfred.me.uk/git.html)。你也可以[配合 mercurial 使用](https://difftastic.wilfred.me.uk/mercurial.html)。
如果你是 Emacs 用户,请查看[这篇博客文章](https://tsdh.org/posts/2022-08-01-difftastic-diffing-with-magit.html),其中介绍了在 magit 中使用 difftastic 的一种方法,以及 [difftastic.el](https://github.com/pkryger/difftastic.el)。
### Difftastic 能与我喜欢的工具集成吗?
可能不行。Difftastic 还很年轻。可以考虑为你喜欢的工具编写一个插件,我会将它链接到 README 中!
### 解析错误怎么办?
默认情况下,只要遇到解析错误,difftastic 就会回退到面向行的 diff。
这是一个保守的选择,以确保 difftastic 绝不会将两个语法不同的文件声明为相同。
如果文件使用了解析器无法理解的语言特性,或者该语言在解析前依赖于预处理器(例如 C++),或者文件确实存在语法错误,就可能发生解析错误。
在实践中,当只有少量轻微的解析错误时,difftastic 几乎总能产生良好的结果。建议在使用 difftastic 时允许少量的解析错误。
```
$ export DFT_PARSE_ERROR_LIMIT=20
$ difft foo1.c foo2.c
```
### Difftastic 能帮我处理合并冲突吗?
可以!从 0.50 版本开始,difftastic 能够理解合并冲突标记(即 `<<<<<<<`、`=======` 和 `>>>>>>>`)。
将包含冲突的文件作为单个参数传递给 difftastic。Difftastic 将构造两个冲突文件并对它们进行 diff。
```
$ difft file_with_conflicts.js
```
### Difftastic 能执行合并操作吗?
不能。AST 合并是一个难题,difftastic 并不解决这个问题。
从文本 diff 的角度来看,AST diff 是一个有损过程。Difftastic 会忽略语法上不重要的空白字符,但合并需要跟踪空白字符。
不过,[mergiraf](https://mergiraf.org/) 工具确实提供了基于 tree-sitter AST 的合并功能。
### Difftastic 可以忽略重新排序吗?
不能。Difftastic 始终认为顺序很重要,因此比较 `set(1, 2)` 和 `set(2, 1)` 会显示变化。
如果你在比较 JSON,建议在将它们传递给 difftastic 之前先对键进行排序。
```
$ difft <(jq --sort-keys < file_1.json) <(jq --sort-keys < file_2.json)
```
另请参阅手册中的[棘手情况:无序数据类型](https://difftastic.wilfred.me.uk/tricky_cases.html#unordered-data-types)。
### 我可以使用 difftastic 来检查语法变化而不进行 diff 吗?
可以。Difftastic 可以检查两个文件是否具有相同的 AST,而无需计算 diff。这比正常的 diff 快得多,并且对于构建检查变化的工具非常有用。
例如:
```
$ difft --check-only --exit-code before.js after.js
```
如果没有语法变化,这将把退出代码设置为 0;如果发现变化,则设置为 1。
### 为什么我的终端里没有显示颜色?
Difftastic 默认使用 ANSI 高亮颜色,但有些终端主题会将高亮颜色显示为灰色。Solarized 就是一个流行的此类主题。
如果你是 Solarized 用户,请使用 `export DFT_BACKGROUND=light` 来禁用高亮颜色,或者尝试不同的终端配色方案。
### 它是如何工作的?
Difftastic 将结构化 diff 视为一个图问题,并使用 Dijkstra 算法。
我的[博客文章](https://www.wilfred.me.uk/blog/2022/09/06/difftastic-the-fantastic-diff/)介绍了其设计,手册中也有[内部原理章节](https://difftastic.wilfred.me.uk/diffing.html)。
## 翻译
+ [中文](./translation/zh-CN/README-zh-CN.md)
## 许可证
Difftastic 是基于 MIT 许可证的开源软件,详见 LICENSE。
本仓库还在 `vendored_parsers/` 目录中包含了其他作者编写的 tree-sitter 解析器。这些解析器混合使用了 MIT 许可证和 Apache 许可证。详见 `vendored_parsers/*/LICENSE`。
`sample_files/` 中的文件也遵循 MIT 许可证,除非其文件头中另有说明。
标签:Diff工具, Git工具, IPv6支持, Rust, SOC Prime, 云安全监控, 代码审查, 代码格式化, 代码比较, 可视化界面, 安全可观测性, 差异对比, 开发工具, 文本差异, 版本控制, 结构化Diff, 编程语言, 网络流量审计, 语法分析, 通知系统, 静态分析
