最稳操作是 go get github.com/xxx/yyy@v1.2.3,仅更新目标模块并自动同步 go.mod 和 go.sum,不递归升级间接依赖;漏写 @ 会拉 latest 导致 v2+ 版本路径错误。

只更新目标模块,不碰其他依赖
最稳的操作是 go get github.com/xxx/yyy@v1.2.3。它只改你指定的那一个模块版本,go.mod 和 go.sum 会自动更新,但不会递归升级任何间接依赖——哪怕那些间接依赖已经严重过时。
常见错误是漏写 @:直接跑 go get github.com/xxx/yyy 会拉 @latest,可能跳到 v2.x,而 Go 要求 v2+ 必须改 import 路径(比如加 /v2),否则编译直接报错 import path does not contain version。
- 版本号必须显式写全,如
v1.2.3、v1.2.3-0.20260520101522-3f5e566(commit hash 生成的伪版本) -
@master或@main不推荐,会在go.mod里存成不稳定伪版本,CI 构建可能失败 - 执行后记得补一句
go mod tidy——它不会帮你下载新包,但会把该模块新增的间接依赖补进go.mod
升级前先看清能升到哪一版
用 go list -m -u github.com/xxx/yyy 查当前模块是否可更新、最新兼容版是什么。输出里带 [behind] 才说明真有新版可升;[newest] 就不用动;[disallowed] 多半是被 replace 或 exclude 锁死了。
别信 go list -m -u all 的全部输出——它会列出所有间接依赖,但很多你根本没 import,升了也没用,反而增加冲突风险。
- 想看某模块所有可用版本:
go list -m -versions github.com/xxx/yyy - 输出里如果 latest 是
v2.0.0,而你代码还在用import "github.com/xxx/yyy",那就不能直接@latest,得先改路径 -
go list -m -json输出结构化数据,适合脚本过滤,比如只挑出主版本相同的升级项
补丁级升级最安全,但得手动触发
go get -u=patch ./ 是生产环境首选。它只会把 v1.9.1 → v1.9.2 这类补丁升级,绝不会动次版本(v1.9.x → v1.10.0)或主版本。
注意 ./ 是关键:不加路径,go get -u=patch 只作用于当前目录的 main 包;加了才扫描整个模块下所有子包的 import,确保所有 direct 依赖都打上补丁。
- 这个命令不会升级
// indirect标记的包,哪怕它们也存在安全漏洞 - 升级后务必跑
go test ./——有些 patch 版本会悄悄改行为,比如net/http的超时默认值 - CI 中建议固定加
-v参数:go mod tidy -v,方便一眼看出哪些模块被删/被加
大版本升级不是命令能解决的事
从 v1 升到 v2 不是 go get 一下就行的。Go 强制要求模块路径带 /v2 后缀,意味着你要同时改三处:
-
go.mod里 module 声明改成example.com/mymodule/v2 - 所有
import语句从"example.com/mymodule"改成"example.com/mymodule/v2" - 调用方代码里所有 API 使用方式,得对照新版本 changelog 检查 breaking change
最容易被忽略的是间接依赖链里的 v2 冲突:比如 A 依赖 v1,B 依赖 v2,而你的代码同时 import A 和 B,Go 会尝试选一个兼容版本,但往往失败。这时得用 replace 或 exclude 主动干预,而不是硬扛。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











