sem:1480⭐的语义版本控制CLI,让代码diff进入实体级别
sem:1480⭐的语义版本控制CLI,让代码diff进入实体级别
传统Git diff基于文本行,当代码被格式化或变量重命名时,diff会变得嘈杂且难以阅读。sem 是一个基于tree-sitter的语义版本控制工具,它将diff粒度从”行”提升到”代码实体”级别。
核心特性
实体级Diff
不同于普通diff显示”第X行被修改”,sem能理解代码结构,显示”函数calculateTotal被修改”、“结构体User添加了字段email”。
# 查看语义diff
sem diff HEAD~1
# 输出示例:
# Modified: function calculateTotal in src/cart.js
# - return price * quantity
# + return price * quantity * (1 - discount)
语义Blame
追踪某个函数或变量的历史修改,而不是某行代码。
# 查看函数的修改历史
sem blame src/cart.js calculateTotal
依赖影响分析
修改一个函数时,sem能分析出哪些其他函数依赖于它,帮助评估变更影响范围。
# 分析变更影响
sem impact src/cart.js calculateTotal
可视化依赖图
生成代码实体间的依赖关系图,理解项目架构。
# 生成依赖图
sem graph --output deps.dot
技术实现
sem的核心是tree-sitter语法解析器,目前已支持21种语言:
- 系统级: C, C++, Rust, Go
- Web: JavaScript, TypeScript, HTML, CSS
- JVM: Java, Kotlin, Scala
- 其他: Python, Ruby, PHP, C#, Swift, OCaml, Haskell, Lua, Elm
解析代码后,sem提取语义实体(函数、类、变量等),构建实体关系图,所有的diff、blame、impact分析都基于此图结构进行。
安装
# 从源码编译
git clone https://github.com/Ataraxy-Labs/sem.git
cd sem
cargo install --path .
# 或使用预编译二进制文件(未来计划)
使用场景
代码审查
在PR review时,sem能清晰展示哪些逻辑被修改,过滤掉格式化变动:
sem diff main...feature-branch
重构辅助
重命名变量或提取函数时,确认所有相关地方都已更新:
sem blame src/utils.js helperFunction
架构分析
生成模块依赖图,发现循环依赖或过度耦合:
sem graph --module-level --output architecture.dot
dot -Tpng architecture.dot -o architecture.png
项目信息
| 属性 | 详情 |
|---|---|
| 仓库 | https://github.com/Ataraxy-Labs/sem |
| 语言 | Rust |
| Stars | 1,480 |
| Forks | 44 |
| 许可证 | MIT |
| 活跃度 | 持续更新(日增约50⭐) |
与Git的关系
sem不替代Git,而是作为Git的增强工具:
- sem读取Git历史进行分析
- 可与现有Git工作流无缝集成
- 支持在Git hooks中调用sem进行代码分析
# 在pre-commit hook中使用
sem diff --staged --check-impact
总结
对于大型代码库或频繁重构的项目,sem提供了传统版本控制无法提供的语义层洞察。虽然项目相对年轻,但基于tree-sitter的稳健解析能力和Rust的高性能实现,使其成为开发者工具箱中有价值的补充。