Git Tag 必须为 vX.Y.Z 格式且 module 路径须与仓库地址一致,否则 Go 模块无法识别;打 tag 前需确保代码可构建、测试通过、go.mod 正确,并验证 proxy 索引。

Git Tag 名字必须匹配 vX.Y.Z 格式才能被 Go 模块识别
Go 的模块系统(go mod)只把形如 v1.2.3、v0.1.0 这样的 tag 当作语义化版本,1.2.3 或 release-v1.2.3 都会被忽略——go list -m -versions 不显示,go get 也拉不到。
实操建议:
- 打 tag 前先确认当前 commit 已提交且干净:
git status无未提交变更 - 用带
v前缀的格式:git tag v1.2.3,不是git tag 1.2.3 - 推送到远程时显式推送 tag:
git push origin v1.2.3,或一次性推所有本地 tag:git push origin --tags - 如果误打了不合规的 tag(比如漏了
v),删掉重打:git tag -d 1.2.3 && git push origin :refs/tags/1.2.3
go.mod 文件里的 module 路径必须和代码仓库地址一致
比如你的项目托管在 github.com/user/repo,那 go.mod 第一行必须是 module github.com/user/repo。否则即使 tag 打对了,go get github.com/user/repo@v1.2.3 会报错:invalid version: unknown revision 或直接 fallback 到 pseudo-version。
常见错误现象:
立即学习“go语言免费学习笔记(深入)”;
- 从 GitHub fork 后改了
go.mod中的 module 名,但没同步更新导入路径,导致依赖方无法解析 - 本地开发用
module example.com/repo测试,发布前忘了改成真实域名 - 用了子模块路径(如
github.com/user/repo/v2),但没在go.mod里声明v2后缀,也不支持go get @v2.0.0
打 Tag 前要确保 go build 和 go test 全部通过
Tag 本质是对某次 commit 的“快照签名”,一旦推送到远程,就不该再修改。如果 tag 对应的代码编译失败、测试 panic、或 go mod tidy 报错,下游用户 go get 后第一件事就是卡住——没人会帮你 debug 一个已发布的版本。
推荐检查顺序(可写成 pre-tag 脚本):
- 运行
go mod tidy并提交go.sum变更 - 执行
go build ./...(确保所有 main 包可构建) - 跑关键测试:
go test -short ./...;如有集成测试,至少保证-short下全过 - 验证模块版本发现:
go list -m -versions .应该列出刚打的 tag
使用 go list -m -versions 和 go get -v 验证发布结果
别只信 git push 成功就完事。真正决定下游能否用上的,是 proxy(如 proxy.golang.org)是否已索引到这个 tag。索引有延迟,通常几秒到几分钟,但有时卡住就得查原因。
验证步骤:
- 本地查:
go list -m -versions github.com/user/repo—— 如果没看到新 tag,说明 tag 格式错或没推上去 - 强制绕过本地缓存拉取:
go get -v github.com/user/repo@v1.2.3,观察输出末尾是否出现unzip或download,而非cached - 若失败且提示
unknown revision v1.2.3,大概率是模块路径不一致;若提示no matching versions,通常是 tag 名字不含v或未被 proxy 收录(等 2 分钟再试,或临时加-insecure排查)
最易被忽略的一点:Go 的版本解析是纯字符串匹配,不校验 commit 内容是否真对应 vX.Y.Z 的语义意图。打错 tag 后,只能删掉重来——没有“覆盖发布”这回事。










