go get -u 仅更新直接导入的包,不递归更新间接依赖,且跳过 replace 或 exclude 控制的模块;真正全量更新需用 go get -u ./... 或 go get -u all(Go 1.16+)。

go get -u 会更新哪些依赖
go get -u 默认只更新直接导入的包(即 import 列表里的模块),不会递归更新间接依赖(require 中带 // indirect 标注的)。它还会跳过 go.mod 中已用 replace 或 exclude 显式控制的模块。
常见误操作是以为 go get -u 能“一键拉平”整个依赖树,结果发现 golang.org/x/net 这类间接依赖依然停留在旧版。真正生效的是:go get -u ./...(当前模块下所有包)或 go get -u all(Go 1.16+ 支持,但仅限 module-aware 模式且不含 vendor)。
- Go 1.17+ 默认启用
-mod=readonly,执行go get前需确认未被GOFLAGS="-mod=readonly"锁死 -
go get -u不会降级版本;若某依赖在go.sum中有更高版哈希,而go.mod写着旧版,它也不会主动回退 - 如果模块启用了
replace指向本地路径,-u完全忽略该条目,连检查都不做
使用 go list -m -u 查看可更新项
go list -m -u 是最轻量、最安全的“只读扫描”方式,它不修改任何文件,只列出所有可升级的模块及其最新可用版本。加上 -f '{{.Path}}: {{.Version}} → {{.Latest}}' 可格式化输出,便于快速比对。
注意:该命令依赖 go.mod 中声明的 require 版本范围。如果写的是 github.com/sirupsen/logrus v1.8.1(精确版本),它仍会显示是否有 v1.9.0 可升;但如果写成 github.com/sirupsen/logrus v1.8.0+incompatible,结果可能不准——因为 +incompatible 表示非语义化版本,proxy 可能不提供完整历史。
立即学习“go语言免费学习笔记(深入)”;
- 加
-json参数可输出结构化数据,适合脚本解析(如筛选"Latest": "v2.0.0"且"Version" != "Latest"的项) -
go list -m -u all会包含所有间接依赖,但耗时明显增加,CI 中慎用 - 某些私有模块若未配置
GOPRIVATE,此命令会报unrecognized import path,不是 bug,是网络策略拦截
go mod tidy -compat=1.20 强制适配新版 Go
当升级 Go 版本(如从 1.19 到 1.20)后,部分依赖可能因底层 API 变更而编译失败。go mod tidy -compat=1.20 不是升级依赖本身,而是让 go 工具链按 Go 1.20 的语义重新解析 go.mod,自动调整 require 中那些声明了 +incompatible 或未指定 // indirect 的模块版本,以满足新编译器的约束。
典型场景:Go 1.21 移除了 net/http/httptrace 中的某个字段,而你依赖的某个 SDK 在其 go.mod 里锁定了 v0.12.3(该版未适配)。此时 go mod tidy -compat=1.21 可能触发工具链去查找 v0.13.0+ 并写入 go.mod,前提是该模块在 proxy 中发布了兼容版本。
-
-compat参数不影响go.sum校验逻辑,只影响版本选择策略 - 若模块作者未发布适配版,该命令不会“强行绕过”,而是报错提示
no matching versions for query "latest" - 执行前建议先
git stash,因为tidy可能删掉未被引用的require行,也可能新增间接依赖
自动化更新要避开 replace 和 sum 文件校验陷阱
CI/CD 中跑自动更新脚本(如每周 cron 调用 go get -u all && go mod tidy)时,最容易翻车的两个点:一是 replace 规则被意外覆盖,二是 go.sum 哈希不匹配导致 go build 失败。
replace 是开发期便利手段,但若脚本无差别执行 go mod tidy,它可能把 replace github.com/foo/bar => ../bar 替换成线上最新版,直接破坏本地调试流。而 go.sum 问题更隐蔽:自动升级后新版本的校验和未写入,下次 go build 就会卡在 verifying github.com/foo/bar@v1.5.0: checksum mismatch。
- 自动化脚本中必须加
go mod edit -dropreplace=github.com/foo/bar(或保留 replace 的白名单机制),避免误删 - 每次
go get后务必跟go mod download和go mod verify,确保go.sum完整且可复现 - Git 提交前检查
go.mod是否含未预期的// indirect新增行——这往往意味着某依赖悄悄引入了新上游,可能带来兼容性风险










