golangci-lint本身不支持增量检查,需通过git diff --name-only HEAD -- '*.go' | xargs -r golangci-lint run --timeout=60s仅扫描新增/修改的Go文件;它无--new-from-rev等参数,全量分析文件,CI中须适配PR基准分支并显式指定配置。

golangci-lint 怎么只检查 Git 新增/修改的代码
它本身不支持“仅报告本次变更引入的问题”,必须靠 Git 配合实现——本质是让 golangci-lint run 只扫描被 git diff 标记为新增或修改的 Go 文件,跳过历史代码。
直接用 git ls-files -m -o --exclude-standard -- '*.go' 不够可靠:它会漏掉刚 git add 但未 commit 的新文件,也包含已删除文件。推荐用 git diff 的 --name-only 输出当前工作区与 HEAD 的差异文件:
-
git diff --name-only HEAD -- '*.go':获取所有被修改、新增(staged 或 unstaged)的.go文件 - 过滤空结果,避免
golangci-lint run对空参数报错 - 传给
golangci-lint run时加--timeout=60s,防止单个大文件拖慢
示例 shell 命令(可放入 pre-commit hook 或 CI 脚本):
git diff --name-only HEAD -- '*.go' | grep '\.go$' | xargs -r golangci-lint run --timeout=60s
为什么不能依赖 --new-from-rev 或类似参数
golangci-lint 官方从没提供 --new-from-rev、--since 这类参数。所谓“增量检查”是社区误传,它的设计模型就是全量扫描指定路径下的文件,没有内置的 Git-aware 比较逻辑。
立即学习“go语言免费学习笔记(深入)”;
有人尝试用 --fix + git status 组合模拟,但风险高:
-
--fix可能自动改写非本次修改的文件(如格式化整包),污染 diff - 若某次提交中删了 10 行、加了 5 行,
golangci-lint仍会对整个文件重分析,无法精确到行级变更 - CI 中若用
git diff origin/main,需确保工作目录 clean,否则HEAD指向不准
CI 中安全落地的关键点
GitHub Actions / GitLab CI 等环境里,git diff 默认只看到 merge commit 的两头,容易漏掉 PR 中真正改动的文件。必须显式配置:
- GitHub Actions:用
github.event.pull_request.base.sha替代HEAD,对比 PR base 分支 - GitLab CI:用
$CI_MERGE_REQUEST_TARGET_BRANCH_NAME+git diff $CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD - 始终加
--out-format=github-actions(GitHub)或--out-format=checkstyle(其他),让问题能正确定位到行 - 禁用
--fix:CI 中修复应由开发者本地完成,CI 只做门禁
最易忽略的是:当 PR 修改了 .golangci.yml 自身,golangci-lint run 仍会按旧配置执行——因为 Git diff 不会触发配置重载。必须在脚本开头先 git checkout HEAD -- .golangci.yml 或强制指定 -c .golangci.yml。


















