Go模块发布新版本不会自动升级下游项目,require声明的是精确版本而非范围,仅当显式执行go get或满足MVS约束时才会更新;go mod tidy不升级版本,replace和未推送tag也会阻断更新。

Go 模块发布新版本时,依赖传递不会自动升级下游项目所用的版本——除非你显式触发更新或满足特定条件。 这是很多团队在发版后发现“别人没用上新功能”或“安全补丁没生效”的根本原因。
go.mod 中 require 的版本号决定实际使用的版本
下游项目 go.mod 里写的是 github.com/yourorg/lib v1.2.3,那它就只会用这个精确版本,哪怕你已发布 v1.2.4 或 v1.3.0。Go 不会主动拉取更新,也不做“小版本自动升级”这类隐式行为。
- 只有执行
go get github.com/yourorg/lib@latest或go get github.com/yourorg/lib@v1.3.0才会更新require行并下载新代码 -
go mod tidy不会升级已有依赖版本,只补全缺失项、清理未使用项 - 如果下游项目用了
replace指向本地路径或 fork,那 even@latest也无效
间接依赖的版本由最小版本选择(MVS)算法决定
当多个直接依赖都引入了同一个模块(比如 golang.org/x/text),Go 会选一个能同时满足所有约束的最低兼容版本。你发了个新版本 v0.14.0,但只要没人显式要求它,MVS 就不会选它——哪怕它是最新版。
- MVS 规则:不是“选最新”,而是“选能满足全部 require 的最小版本”
- 例如 A 依赖
x/text v0.12.0,B 依赖x/text v0.13.0,最终选v0.13.0;但如果 B 改成v0.11.0,结果就变成v0.12.0 - 想强制升级?得让至少一个直接依赖把
require改到你要的版本,再go mod tidy
打 tag 后不推送到远程仓库,下游根本看不到新版本
Go Modules 从远程模块代理(如 proxy.golang.org)或源码仓库(如 GitHub)拉取模块,不是读本地文件系统。你本地 git tag v1.5.0 但没 git push --tags,下游执行 go get @v1.5.0 会报错:not found。
立即学习“go语言免费学习笔记(深入)”;
- 确认推送:运行
git ls-remote origin --tags | grep v1.5.0 - 私有模块要注意 GOPROXY 配置是否包含你的私仓地址(如
https://goproxy.example.com) - 如果用了
replace临时指向本地路径,记得发版前删掉——否则别人无法复现构建
最容易被忽略的一点:模块发布后,go.sum 文件里的哈希值必须匹配新版本内容。如果 tag 内容变更但没改 tag 名(比如 force push 覆盖旧 tag),会导致校验失败,go build 直接退出。语义化版本不是摆设,v1.x.y 的每次变更都应对应一次不可变的 commit + tag。


















