Sem – 语义版本控制。Git 上的实体级差异
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)
| Language | Extensions | Entities |
|---|---|---|
| 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
| Format | Extensions | Entities |
|---|---|---|
| JSON | .json | 属性、对象(RFC 6901 路径) |
| YAML | .yml .yaml | 章节、属性(点路径) |
| TOML | .toml | 章节、属性 |
| CSV | .csv .tsv | 行(第一列作为标识) |
| Markdown | .md .mdx | 基于标题的章节 |
Everything else falls back to chunk‑based diffing.
其他所有情况均回退为基于块的差异比较。
匹配工作原理
三阶段实体匹配:
- 精确 ID 匹配 – 前后相同实体 → 已修改或未更改。
- 结构哈希匹配 – 相同的 AST 结构,名称不同 → 重命名或移动(忽略空白/注释)。
- 模糊相似度 – > 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