替换成默认 diff 之前有个实际坑得说一下:difftastic 的输出不是标准 unified diff,一旦把它设成 diff.external 全局生效,git diff 就再也吐不出能被 git apply 直接吃的 patch 了。我自己后来改成只用它当 viewer——走 git difftool 或者给 git diff 配个 alias 包一层,平时 review 用它的高亮,真要生成补丁还是回退原生 diff。不然哪天给同事发 patch、或者 CI 里跑消费 diff 输出的脚本就傻眼,官方文档其实也提示了这点。
另外它的强项得说准:真正被它压下去的噪音是"结构移动"——函数挪了位置、参数顺序调了、一段代码从文件头搬到了文件尾,这种文本 diff 会整段标红,而它比对的是语法树,能识别出"这段其实没变只是换了地方"。但你举的"改个变量名"恰恰相反,变量名是实打实的内容改动,它照样会高亮出来,别误会成它能自动忽略重命名。能帮你抹掉的主要是纯格式和空白层面的差异。
性能这块帖子没提。tree-sitter 先把两边 parse 成树再做树比对,算法是启发式的,几千行的重构 PR 通常很顺,但遇到嵌套极深或者特别畸形的输入,匹配耗时会非线性地涨。真碰上那种几万行的单体文件,有时候反应还不如文本 diff 干脆。所以"大重构爽"不代表它对一切体量都线性友好。
还有个隐性上限:效果天花板取决于 tree-sitter 对应语言 grammar 的成熟度。其实主流那几十种确实开箱即用,但小众语言或者语法边缘 case,parse 不准的话差异反而会漏。真要较真,最好拿自己最常改的语言试几个边界场景再决定全网铺开。
你们现在是直接顶替 diff.external 还是只当 tool 用?我后来选了后者,省心。