golangci-lint不支持--diff参数,因其设计基于文件/目录驱动的AST加载,无法解析diff文本中的包结构、行号偏移及调用链影响;官方推荐用--new-from-rev结合git获取变更文件进行增量检查。

golangci-lint 本身不支持直接读取 diff 补丁文件做增量分析——它没有 --diff 或 --patch 这类原生命令行参数。想用它做 PR/MR 级别的轻量审查,必须绕过“全量扫描”这个默认行为,靠外部工具配合实现。
为什么不能直接 golangci-lint --diff patch.diff
golangci-lint 的设计模型是“文件/目录驱动”,它依赖 Go 的 build.Context 和 loader 加载源码 AST,而 diff 文件(如 git diff 输出)只是文本快照,不含包结构、导入路径或构建约束信息。强行解析 patch 会导致:
• 无法识别被修改函数所属的 package 或 import scope
• 行号偏移错乱(add/delete 混合后上下文行号失效)
• 跳过未在 patch 中显式出现但被调用链影响的函数(比如改了 A 函数,B 函数调用了 A,但 B 没出现在 diff 里)
真正可行的增量方案:用 git + --new-from-rev
golangci-lint 提供了官方支持的增量入口:--new-from-rev。它不解析 patch,而是让 git 告诉它“哪些文件在指定提交后被修改过”,再只对这些文件执行 lint:
- 在 CI 中检查 PR 变更(以 GitHub Actions 为例):
golangci-lint run --new-from-rev=origin/main - 本地预检当前分支相对于 main 的改动:
golangci-lint run --new-from-rev=main - 注意:
--new-from-rev必须指向一个已存在的 commit/ref,不能是任意字符串;如果目标分支没 fetch 过,会报fatal: ambiguous argument 'origin/main': unknown revision - 该选项默认只检查“新增或修改的 Go 文件”,自动跳过删除的文件和非 .go 文件,行为稳定且与 git status 语义一致
配合 open-code-review 做 diff 级语义审查
如果你需要更细粒度的“仅检查改动行所在函数体”或“带上下文的块级规则”,golangci-lint 就力不从心了。这时候应该切换到专为 diff 设计的工具:
立即学习“go语言免费学习笔记(深入)”;
-
open-code-review会把git diff解析成行级变更集合,再根据每行所在的函数/方法边界提取 AST 子树,确保规则(如errcheck、staticcheck)只作用于实际被修改的逻辑块 - 它能识别“这一行虽然改了,但它属于一个被
//nolint标记的函数”,而 golangci-lint 的--new-from-rev会整文件扫描,无法感知这种行级抑制 - 想试水?直接运行:
open-code-review review --diff "$(git diff origin/main)" --lang go - 注意:
open-code-review不替代golangci-lint,而是补位——前者管“这次改的有没有问题”,后者管“改完后的文件整体是否健康”
真正的难点不在命令怎么写,而在于厘清“谁该负责哪一层”。用 --new-from-rev 是最省事的增量起点,但一旦你开始关心“为什么这行改动会触发并发风险”,就得把 diff 当输入、把 AST 上下文当燃料,交给更垂直的工具来处理。


















