☰
如何支持38种编程语言:weave的tree-sitter语言注册表、五场景覆盖测试与为何刻意放弃Vue和Haskell
2026/10/14 15:53:52 网站建设 项目流程

【免费下载链接】weave

Entity-level git merge driver. Resolves false conflicts git invents when independent agents edit the same file. ~95% reduction vs. line-based merge.

项目地址:https://gitcode.com/gh_mirrors/weave17/weave
点击查看免费下载

weave 是一款实体级(entity-level)Git 合并驱动,基于 tree-sitter 语言注册表对 38 种编程语言和格式做函数、类、键级别的语义合并,能消除 Git 按行合并时产生的大量"假冲突"。本文带你拆解 weave 的语言支持体系:注册表如何做到"零手工维护"、每种语言必须通过的五个覆盖测试,以及为什么 Vue 和 Haskell 被刻意排除在外。

一、为什么"支持语言"是 weave 的核心工程

Git 的合并以行为单位:两个分支只要往同一文件的不同函数里加代码,就可能因行区间重叠而报冲突。weave 的做法相反——先用 tree-sitter 把 base、ours、theirs 三个版本解析成语义实体(函数、类、JSON 键等),再在实体粒度上做三路合并。

这意味着"支持一种语言"不是加个配置项那么简单,它要求三件事同时成立:

  • 有可工作的 tree-sitter 语法解析器;
  • 解析出的实体模型足够细(按定义拆分,而不是整文件一块);
  • 该模型下的合并行为经过验证:该干净的干净,该冲突的必须冲突。

下图演示了典型场景:两个分支各加一个函数,Git 报冲突,weave 干净合并。

二、tree-sitter 语言注册表:唯一的真相来源

很多工具用一张"手工维护的支持语言清单",清单和解析器能力迟早脱节。weave 的设计是派生而非罗列:

  • 合并引擎持有一个静态的 parser registry(crates/weave-core/src/merge.rs),由 sem-core 的create_default_registry构建,包含全部编译进来的 tree-sitter 语法。
  • weave setup写入.gitattributes的扩展名列表,直接调用supported_merge_extensions()(merge.rs)从注册表实时读取:注册表认识的所有扩展名,减去被拒绝的,就是 setup 会声明的。上游新增一个语法,setup 自动多认领对应扩展名,两者不可能漂移。
  • 反向也有守卫:parity 测试(crates/weave-core/tests/setup_extension_coverage.rs)断言"每一个注册扩展名要么被 setup 发射、要么被显式拒绝,绝不能悄悄漏掉",并额外检查 setup 不会发明引擎无法兑现的覆盖(如.lock这类不可解析文件保持 Git 默认行合并)。

当前这 38 项覆盖:TypeScript、TSX、JavaScript、Python、Go、Rust、Java、C、C++、Ruby、C#、PHP、Swift、Kotlin、Scala、Dart、Elixir、Bash、Fish、Fortran、Perl、OCaml、Zig、Elm、Clojure、EDN、D、Lua、Nix、SQL、HCL/Terraform、LaTeX、XML、JSON、YAML、TOML、CSV、Markdown。

值得一提的细节:INI 文件(.ini/.cfg)没有 tree-sitter 语法,但也走了注册表通道(LINE_RULE_EXTENSIONS),采用 Git 行合并加"同一 section 内双方新增的键取并集"的规则——能力边界在哪,行为就精确到哪。

三、五场景覆盖测试:每种语言必须通过 5 道关卡

进入支持列表的"入场券"在 crates/weave-core/tests/language_coverage.rs。每种语言用三个可互换的定义(alpha/beta/gamma)组装出相同的五组合成三路合并,全部通过才允许列入:

场景操作期望结果
1. 不相交新增双方各加一个不同定义干净合并,两个新增都保留
2. 新增对修改ours 改写定义、theirs 新增定义干净合并,两边编辑都不丢
3. 矛盾改写双方把同一定义改成不同值必须冲突,且冲突框携带双方声明
4. 单侧静止theirs 无变化干净合并,结果与 ours 逐字节一致
5. 相同编辑两次双方做了完全相同的修改干净合并,编辑只出现一次

场景 1、2、4 验证"不丢东西";场景 3 防止引擎为求"全干净"而悄悄吞掉编辑;场景 5 验证幂等。测试文件的注释说得很直白:过不了全部五项的语言,不配进支持列表(language_coverage.rs)。

四、为何刻意放弃 Vue、Svelte、ERB 和 Haskell

这是本文标题的重点,也是 weave 最有纪律性的地方:这四类文件能被解析,但合并效果比 Git 还差,所以被显式拒绝(DECLINED_EXTENSIONS,见 merge.rs),交给 Git 的行合并处理。

原因都出在实体模型太粗(language_coverage.rs):

  • .vue/.svelte:整个<script>块是一个实体。于是脚本里任何位置的编辑都互相竞争——双方各加两个函数这种最常见的合并直接冲突,且冲突标记框会从函数签名和函数体中间切过。
  • .erb:整个模板是一个实体,两个互不相干的<% def %>新增也会冲突,标记会把<% end %>与代码块分离。
  • .hs(Haskell):解析器把类型签名当作实体,绑定行却算作间隔文本。不相交新增时两边会漂移:输出把beta :: String配上了alpha = "base_value",一个绑定被复制、另一个被框住——这是丢失工作成果,而不是冲突。

weave 的判断标准不是"能解析就算支持",而是"不能比 Git 更差"。这些文件走行合并是当下更优的答案。它们随时可能回来:一旦解析器获得真正的按定义实体模型,把 fixture 加回 sweep 测试,通过五项就能重新赢得支持列表中的一席之地。

这种"拒绝清单"本身也被测试看守:Svelte 的整个复合后缀家族(.svelte.js、.svelte.spec.ts等)都必须拒绝,注册表若新增遗漏的变体,parity 测试会直接让构建失败。

五、从注册表到工作流:一次 setup 如何生效

理解了三道防线(注册表 → sweep 测试 → parity 守卫),再看用户侧的落地就一目了然:

weave setup # 从注册表派生 .gitattributes,逐扩展名写入 merge=weave

setup 的扩展名映射逻辑在 crates/weave-cli/src/commands/setup.rs:注册表扩展名减去拒绝清单,加上 INI 行规则类,映射成*.ts、*.kt等 glob。weave setup --global可让所有仓库默认走 weave,--local只写.git/info/attributes不影响他人。

从 0.5.3 的 CHANGELOG 可以看到这套体系的威力:引擎早已能解析 Kotlin、Terraform、OCaml 等语言,只是 setup 从未来认领;改用注册表派生后,17 个扩展名一次性补齐,总数到达 38,且 Vue/Svelte/ERB/Haskell 被明确移出。

其他兜底规则也值得知道:超过 1MB 的文件、二进制文件、无解析器的类型自动回退到 Git 行合并(STRUCTURE_LIMIT_BYTES,见 merge.rs)——注册表声明的每一行承诺,引擎都有能力兑现。

六、安装与上手

brew install weave # 或源码构建(需要 Rust 工具链)

源码构建需要两个二进制(CLI 与 Git 实际调用的 driver):

git clone https://gitcode.com/gh_mirrors/weave17/weave cd weave cargo install --path crates/weave-cli # weave 命令 cargo install --path crates/weave-driver # git 调用的合并驱动

装好后在任意仓库执行weave setup,日常照常用git merge:真实冲突落地为带refused_by:说明的标记,随后用weave explain <file>查看每个冲突实体的详情、weave check校验你的手工解决、weave preview <branch>无副作用地预演合并结果。

总结

weave 对"38 种语言支持"的态度可以概括为三条工程纪律:

  1. 派生而非罗列——支持范围永远等于 tree-sitter 注册表的实时能力减去显式拒绝集,杜绝清单漂移;
  2. 测试即准入——五场景 sweep 是每种语言的硬门槛,"过不了就不列";
  3. 拒绝也是特性——Vue、Svelte、ERB、Haskell 因实体模型过粗被刻意排除,宁可交还给 Git 行合并,也不制造更差的冲突。

正是这种克制,让 weave 在 31 个手工场景基准上保持 31/31 的正确率——包括那两处"合并成功反而是错的"装饰器场景。

【免费下载链接】weave

Entity-level git merge driver. Resolves false conflicts git invents when independent agents edit the same file. ~95% reduction vs. line-based merge.

项目地址:https://gitcode.com/gh_mirrors/weave17/weave
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询