Sem – 语义版本控制。Git 上的实体级差异

发布: (2026年3月8日 GMT+8 14:01)
5 分钟阅读

Source: Hacker News

概述

语义化版本控制。基于 Git 的实体级差异。

与其显示 第 43 行已更改,sem 会告诉你 src/auth.ts 中添加了函数 validateToken

sem diff

┌─ src/auth/login.ts ──────────────────────────────────

│  ⊕ function  validateToken          [added]
│  ∆ function  authenticateUser       [modified]
│  ⊖ function  legacyAuth             [deleted]

└──────────────────────────────────────────────────────

┌─ config/database.yml ─────────────────────────────────

│  ∆ property  production.pool_size   [modified]
│    - 5
│    + 20

└──────────────────────────────────────────────────────

Summary: 1 added, 1 modified, 1 deleted across 2 files

安装

从源码构建(需要 Rust):

git clone https://github.com/Ataraxy-Labs/sem
cd sem/crates
cargo install --path sem-cli

或者从 GitHub Releases 获取二进制文件。

用法

适用于任何 Git 仓库。无需额外设置。

  • 工作区更改的语义差异

    sem diff
  • 仅已暂存的更改

    sem diff --staged
  • 指定提交

    sem diff --commit abc1234
  • 提交范围

    sem diff --from HEAD~5 --to HEAD
  • JSON 输出(用于 AI 代理、CI 流水线)

    sem diff --format json
  • 从 stdin 读取文件更改(不需要 Git 仓库)

    echo '[{"filePath":"src/main.rs","status":"modified","beforeContent":"...","afterContent":"..."}]' \
      | sem diff --stdin --format json
  • 仅特定文件类型

    sem diff --file-exts .py .rs
  • 实体依赖图

    sem graph
  • 影响分析(如果此实体更改会导致哪些破坏?)

    sem impact validateToken
  • 实体级别的 blame

    sem blame src/auth.ts

What it parses

Programming languages (13)

LanguageExtensionsEntities
TypeScript.ts .tsx函数、类、接口、类型、枚举、导出
JavaScript.js .jsx .mjs .cjs函数、类、变量、导出
Python.py函数、类、装饰定义
Go.go函数、方法、类型、变量、常量
Rust.rs函数、结构体、枚举、实现、特性、模块、常量
Java.java类、方法、接口、枚举、字段、构造函数
C.c .h函数、结构体、枚举、联合、typedef
C++.cpp .cc .hpp函数、类、结构体、枚举、命名空间、模板
C#.cs类、方法、接口、枚举、结构体、属性
Ruby.rb方法、类、模块
PHP.php函数、类、方法、接口、特性、枚举
Fortran.f90 .f95 .f函数、子程序、模块、程序

Structured data formats

FormatExtensionsEntities
JSON.json属性、对象(RFC 6901 路径)
YAML.yml .yaml章节、属性(点路径)
TOML.toml章节、属性
CSV.csv .tsv行(第一列作为标识)
Markdown.md .mdx基于标题的章节

Everything else falls back to chunk‑based diffing.
其他所有情况均回退为基于块的差异比较。

匹配工作原理

三阶段实体匹配:

  1. 精确 ID 匹配 – 前后相同实体 → 已修改或未更改。
  2. 结构哈希匹配 – 相同的 AST 结构,名称不同 → 重命名或移动(忽略空白/注释)。
  3. 模糊相似度 – > 80 % 令牌重叠 → 可能的重命名。

这使得 sem 能检测重命名和移动,而不仅仅是添加和删除。结构哈希还可以将表面更改(空白、格式)与真实逻辑更改区分开来。

JSON 输出

{
  "summary": {
    "fileCount": 2,
    "added": 1,
    "modified": 1,
    "deleted": 1,
    "total": 3
  },
  "changes": [
    {
      "entityId": "src/auth.ts::function::validateToken",
      "changeType": "added",
      "entityType": "function",
      "entityName": "validateToken",
      "filePath": "src/auth.ts"
    }
  ]
}

作为库

sem-core 可以作为 Rust 库依赖使用:

[dependencies]
sem-core = { git = "https://github.com/Ataraxy-Labs/sem", version = "0.3" }

weave(语义合并驱动)和 inspect(实体级代码审查)使用。

架构

  • tree‑sitter 用于代码解析(原生 Rust,非 WASM)
  • git2 用于 Git 操作
  • rayon 用于并行文件处理
  • xxhash 用于结构哈希
  • 插件系统用于添加新语言和格式

星标历史

星标历史图表

许可证

MIT 或 Apache‑2.0

0 浏览
Back to Blog

相关文章

阅读更多 »

并非所有摩擦都相同

介绍 最近有很多帖子庆祝“摩擦的消亡”,赞扬 AI 如何消除编写代码的摩擦并提升开发效率

介绍 Attune.js

封面图片:Introducing Attune.js https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads....