跳到主内容
文章阅读

sem 使用教程:只看某个文件变化怎么传参?附常见命令

一篇实用上手文,讲清 `sem` 的基本使用方式,重点解释只看单文件变化时为什么要用 `sem diff -- path/to/file`,并补充 `diff / entities / blame / log / impact / context / verify` 等常见命令。

2026/04/20349 次阅读6 分钟

如果你已经把 sem 装到本机,最该先记住的一件事就是:sem diff 基本沿用了 git diff 的传参习惯。

这件事很重要,因为很多人第一次用 sem 时,会把它当成一个全新的命令行工具去记参数。其实没必要。当前版本的 sem diff --help 已经写得很直接:它支持 git diff syntax,参数里可以传 git refs, files, or pathspecs,也支持 -- paths 这种写法。

所以,如果你的问题是:

我只想看某一个文件的变化,怎么传?

最稳妥的答案就是这一条:


sem diff -- src/foo.ts

为什么这里要写 --

因为在 git diff 的世界里,-- 前面的内容更像版本范围、提交参数或者别的选项,-- 后面的内容才明确表示“这是路径”。

既然 sem diff 明说兼容 git diff 的参数风格,那你就应该按 Git 的脑子来用它。这样最不容易歧义,也最不容易在分支名、commit 和文件路径之间撞车。

我本机直接做了一个最小验证:在临时 Git 仓库里同时改两个文件,然后执行 sem diff -- a.ts,输出只保留了 a.ts 的语义变化。这不是猜测,是实际跑过的。

最常用的几条 sem diff 命令

如果你只是日常用 sem 看改动,先记住下面几条就够了。

看当前工作区里所有未提交改动:


sem diff

只看某个文件的未提交改动:


sem diff -- src/foo.ts

只看已暂存的改动:


sem diff --staged

只看已暂存里某个文件的改动:


sem diff --staged -- src/foo.ts

看一个提交范围里的改动:


sem diff HEAD~1..HEAD

看一个提交范围里某个文件的改动:


sem diff HEAD~1..HEAD -- src/foo.ts

同时筛多个文件也一样:


sem diff -- src/foo.ts src/bar.ts

sem diff src/foo.ts 能不能用

当前版本里,这种写法也是能跑的:


sem diff src/foo.ts

但我不建议你把它当成长期习惯。

原因很简单。今天这个参数也许能被正确理解成文件路径,明天你在一个更复杂的命令里混进了分支名、commit range,或者路径刚好和别的名字撞上,就容易产生歧义。

所以我的建议一直很简单:

只要你在按“路径过滤”思路用 sem diff,就默认写成 -- 路径

也就是:


sem diff -- src/foo.ts

而不是:


sem diff src/foo.ts

前者更像 Git,也更稳。

再补一组高频 diff 用法

如果你不只是“看一下改动”,而是想把 sem 真的塞进日常工作流,那下面这些也很常用。

看某个提交本身的变化:


sem diff --commit HEAD

看更细一点的实体内联变化:


sem diff -v -- src/foo.ts

输出成 JSON,方便喂给脚本、工具链或者 AI:


sem diff --format json -- src/foo.ts

输出成 Markdown,适合贴到文档或评论区:


sem diff --format markdown HEAD~1..HEAD -- src/foo.ts

只分析某几种扩展名:


sem diff --file-exts .ts .tsx

在别的仓库目录里直接执行:


sem diff -C /path/to/repo -- src/foo.ts

除了 diff,这些命令也很常用

如果你把 sem 只当成一个“更聪明的 diff”,其实只用到它一半能力。下面这几条,才是它和普通 Git 工具真正拉开差距的地方。

列出一个文件里的语义实体:


sem entities src/foo.ts

如果你要拿给脚本处理,也可以直接出 JSON:


sem entities src/foo.ts --json

看一个文件里每个实体最后是谁改的:


sem blame src/foo.ts

追某个函数、类或者方法在 Git 历史里的演化:


sem log someEntity

如果同名实体不止一个,最好显式带上文件路径:


sem log someEntity --file src/foo.ts

如果你还想看每次演化里的内容差异:


sem log someEntity --file src/foo.ts -v

看改动一个实体会影响到谁:


sem impact someEntity --file src/foo.ts

只看它直接依赖了什么:


sem impact someEntity --file src/foo.ts --deps

只看谁依赖它:


sem impact someEntity --file src/foo.ts --dependents

只看受影响的测试:


sem impact someEntity --file src/foo.ts --tests

给某个实体抽一份 token budget 受控的上下文,适合喂给 AI:


sem context someEntity --file src/foo.ts --budget 4000

检查函数签名变化有没有把调用方搞坏,尤其适合改完参数列表以后跑一遍:


sem verify --diff

如果你要全量扫当前代码库:


sem verify

这个工具到底是怎么用的

如果你不是只想解决“单文件过滤”这个点,而是想知道 sem 平时该怎么上手,我会这样理解它:

sem 不是替代 Git 的版本控制,而是给 Git 的 diff 增加一层语义视角。

普通 git diff 更擅长告诉你:哪一行变了、哪几行被删了、哪几行被加了。

sem diff 更擅长告诉你:哪个函数变了、哪个类、方法、变量定义变了,以及这些变化在代码结构上意味着什么。

如果你平时 review 代码时最烦“几十行 patch 里看不出核心改动点”,那 sem 的价值就很明显。

我对这个工具的建议用法

如果你刚装好 sem,别一上来就把全部命令都背下来。先把 diff 用顺手。

我建议顺序是这样的:

  1. 先跑 sem diff,感受一下它和普通 git diff 的区别
  2. 接着学会用 -- 路径 只盯某个文件
  3. 再加上 -v--format json--format markdown 这些实用输出方式
  4. 然后开始用 entitiesblamelog 理解代码结构和历史
  5. 最后把 impactcontextverify --diff 这些命令接进 review 和重构流程

对大多数人来说,真正高频的还是这几类:看当前改动、看 staged 改动、看某个提交范围里某个文件的改动、看某个实体的历史、看签名改动有没有波及调用方。

把这几条跑顺了,sem 基本就已经能进你的日常工作流了。

最后给一个最短答案

如果你看到这里,只想拿一句能直接复制的结论,那就是:


sem diff -- 你的文件路径

比如:


sem diff -- lib/main.dart
sem diff -- src/foo.ts
sem diff HEAD~1..HEAD -- src/foo.ts

一句话总结就是:sem diff 可以按 Git 的 pathspec 方式传路径。只看某个文件时,优先写 -- 文件路径,这是当前最稳、最不容易歧义的用法。

返回顶部