每天提交前必须运行go mod tidy,它会删除未引用的require、补全缺失依赖、更新go.sum;跳过将导致CI报错,go.sum必须提交且禁止手动编辑。

每天提交前必须运行 go mod tidy
不是“偶尔跑一下”,而是每次修改 import 或删掉未用包后,立刻执行。它会同步三件事:删掉 go.mod 里没被引用的 require 行、补全缺失的间接依赖、更新 go.sum 校验和。跳过这步,CI 构建时大概率报 missing go.sum entry 或 checksum mismatch。
容易踩的坑:
- 在分支 A 上改了依赖但没
go mod tidy,切到分支 B 后直接go build—— 此时本地缓存可能混入 A 的未提交状态,导致构建结果不可复现 - 多人协作时,有人手动编辑
go.mod增加replace调试本地子模块,却忘了删掉就提交 —— CI 会因找不到本地路径而失败 -
go mod tidy不会自动降级或升级版本,它只做“收敛”。想升级某个库?得先go get github.com/foo/bar@v1.5.0,再tidy
go.sum 必须进 Git,且禁止手动编辑
go.sum 是内容校验快照,不是锁文件。它的每一行都对应一个模块下载内容的 SHA256 哈希值,go build 时强制校验。一旦忽略或删掉它,不同机器拉代码后可能装上被篡改/不一致的依赖。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- Git 提交时检查
go.sum是否有新增/变更行 —— 它应该随go.mod一起变动 - CI 流程中加一行
go mod verify,放在go test前,早于构建暴露问题 - 如果团队用私有仓库(如
git.internal.company.com),必须配置GOPRIVATE=git.internal.company.com/*,否则go mod download会因走 proxy 失败,连带go.sum生成中断
多模块项目中,replace 只用于开发,不进主干
主模块引用本地子模块(如 ./modules/user)时,replace 是唯一可行方式。但它本质是“绕过模块解析”,上线构建时会被拒绝。
关键约束:
-
replace指令必须配对出现在go.mod的require块里,且版本号写成v0.0.0(Go 会忽略该值,只认路径) - 发布前必须人工删除
replace行,并确保子模块已打 tag(格式严格为v1.2.3,不能是1.2.3) - CI 环境建议加
GOFLAGS="-mod=readonly",让go build在遇到replace时直接报错,而不是静默忽略
依赖升级要锁定语义化版本,别信 @latest
go get github.com/sirupsen/logrus@latest 看似省事,实际等于把版本控制权交给上游 —— 下次 @latest 可能已是 v2.x,而 Go 默认不兼容 v2+(需路径含 /v2)。敏捷团队节奏快,没人能随时跟进每个依赖的 breaking change。
安全做法:
- 升级前查
go list -m -versions github.com/sirupsen/logrus,确认可用版本范围 - 明确指定
@v1.9.3这类带v前缀的 tag,而非分支名或 commit hash(后者生成伪版本,难追溯) - 若必须用 fork 或私有修复版,用
replace+go mod tidy,但要在 PR 描述里写清原因和预期生命周期
最常被忽略的一点:模块路径一旦发布 v1.x 就不可变更。比如你发过 v1.0.0,就不能把 go.mod 里的 module github.com/org/foo 改成 github.com/org/bar —— 所有下游 go get 都会失败。路径即契约,改它比改代码影响更大。

















