go get 时应直接使用 @commit-hash,Go 会自动生成合法伪版本号(如 v0.0.0-yyyymmddhhmmss-abc123def456+incompatible),需确保 commit 存在、时间戳为 UTC、哈希至少 12 位。

go get 时怎么指定某个 commit 的伪版本号
Go 模块系统不会让你直接写 git commit hash 当版本,它强制走语义化版本或伪版本号(pseudo-version)。你得让 go get 自己生成并接受那个带 v0.0.0-yyyymmddhhmmss-commit 格式的字符串。
常见错误是手动拼接伪版本号失败——比如时间戳格式不对、没用 UTC、commit 缩写长度不够(必须是 12 位)、或者没加 +incompatible 后缀(当模块没打 v1+ tag 且 go.mod 里没 go 1.16+ 声明时)。
- 执行
go get github.com/user/repo@<code>commit-hash,Go 会自动解析成合法伪版本号并拉取 - 如果失败,先确认该 commit 确实存在于远程 origin(
git ls-remote origin <code>commit-hash) - 若模块已有
v1.xtag,但你想退回到某个旧 commit,仍可用@<code>commit-hash,Go 会生成类似v1.2.3-0.20220514182341-abc123def456的伪版本 - 伪版本中的时间戳是 commit 的 author time(不是 committer time),且必须是 UTC;本地时区不影响
go get解析,但你自己手算会出错
go.mod 里手动写伪版本号要注意什么
你可以直接编辑 go.mod,把 require 行改成伪版本号,但 Go 不会校验格式是否合法——写错会导致后续 go build 或 go list 报错,例如 invalid pseudo-version: major version without preceding dot 或 malformed semantic version。
- 伪版本号必须严格符合
vX.0.0-yyyymmddhhmmss-abcdef123456格式,其中X是主版本数字(如v0或v1),不能是v0.0或v1.2 - 时间部分必须是 14 位(年4+月2+日2+时2+分2+秒2),且为 UTC;commit ID 必须是 12 位以上完整哈希前缀(Go 内部校验至少 12 字符)
- 如果模块没有
go.mod文件(即 legacy repo),Go 会默认加上+incompatible后缀,手动写时也得带上,否则go mod tidy会把它干掉 - 改完
go.mod后,运行go mod download验证能否实际拉到代码,别只靠go mod graph看依赖树
为什么 go list -m -json 显示的 Version 和实际 commit 对不上
go list -m -json 输出的 Version 字段永远是伪版本号(哪怕你 go get 时用了 @v1.2.3),而 Origin 里的 Revision 才是真实 commit hash。这是设计使然:Go 把“版本”和“源码快照”做了抽象隔离。
立即学习“go语言免费学习笔记(深入)”;
- 想确认当前 module 实际对应哪个 commit,看
go list -m -json | jq '.Origin.Revision',不是.Version - 如果
.Version是v0.0.0-00010101000000-000000000000,说明本地没真正拉取过,或者go.mod被手工改坏导致 Go 无法解析 - 在 CI 或离线环境里,别依赖
.Version做 commit 比对;要用git rev-parse查工作目录,或从go mod download -json的输出里取Dir路径再进目录查
replace 指向本地路径后,伪版本号还生效吗
不生效。replace 会让 Go 完全绕过模块代理和校验逻辑,直接读本地文件系统。此时 go list -m 显示的 Version 会变成 (devel),所有伪版本号信息丢失,go mod graph 里也看不到 commit hash。
- 开发调试时用
replace很方便,但发布前务必删掉,否则别人go mod download会失败 - 如果只是想固定某个 commit 又要保留可复现性,优先用
go get @<code>commit-hash,而不是replace -
replace后执行go mod verify会跳过该 module,所以它不能用于验证依赖完整性
go build 在某台机器上突然失败。










