Golang中go get命令为何不再遵循ssh git.url.insteadOf配置?
Golang中go get命令为何不再遵循ssh git.url.insteadOf配置? 我有一个全局的 git 设置:
[url "git@bitbucket.org:"]
insteadOf = https://bitbucket.org/
并且没有本地覆盖或重写。最近,对我自己、我组织中的一些其他人以及我们所有的自动化流水线来说,go get 似乎已经不再遵守这个设置了。如果我运行 go get -x bitbucket.org/organizationname/foo,我看到的是:
# get https://api.bitbucket.org/2.0/repositories/organizationname/foo?fields=scm
# get https://api.bitbucket.org/2.0/repositories/organizationname/foo?fields=scm: 404 Not Found (0.568s)
# get https://proxy.golang.org/bitbucket.org/@v/list
# get https://proxy.golang.org/bitbucket.org/@v/list: 410 Gone (0.076s)
# get https://api.bitbucket.org/2.0/repositories/organizationname/foo?fields=scm
# get https://api.bitbucket.org/2.0/repositories/organizationname/foo?fields=scm: 404 Not Found (0.080s)
go get bitbucket.org/organizationname/foo: reading https://api.bitbucket.org/2.0/repositories/organizationname/foo?fields=scm: 404 Not Found
Go 版本是 go1.16 darwin/amd64(编辑:具体是 go1.16.0,这后来证明很重要),据我所知最近没有改变。我已经确认直接使用 git 命令,例如 git ls-remote git@bitbucket.org:organizationname/foo,可以正常工作并按预期显示分支。这里到底发生了什么?
更多关于Golang中go get命令为何不再遵循ssh git.url.insteadOf配置?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我最近在更新一个私有模块时遇到了与上面帖子中相同的错误。我的 GOPRIVATE 设置是正确的,并且之前使用
go get -x bitbucket.org/org/repo是有效的。
我更新到 go1.18 后,问题得到了解决,现在
go get对于私有仓库可以按预期工作了。
+1
更多关于Golang中go get命令为何不再遵循ssh git.url.insteadOf配置?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
升级之所以有效,是因为Bitbucket在仅提前几天通知的情况下,停止为未正确认证的私有仓库返回403错误,转而用404错误替代。他们的理由(姑且这么说)在此处有描述。没有解释为什么他们认为在周三通过一个没人看的博客宣布一个破坏性变更,并在接下来的周四就采用,且不允许选择退出或提供有用的错误信息,这种做法是合理的。
Go 版本 1.16.14、1.17.7 和 1.18.x 更新了 go get 的行为,使其对 404 错误的响应方式与对 403 错误相同。这修复了该问题。祝那些突然需要更新 Go 版本以维持系统运行,并且在此过程中无法运行任何测试自动化的人好运。
Go 1.16 版本中,go get 命令的行为发生了变化,不再直接使用 Git 的 insteadOf 配置来重写 URL。从 Go 1.16 开始,go get 在获取模块时会优先使用 Go 模块代理(如 proxy.golang.org)和校验和数据库,而不是直接使用 Git 命令。这导致 Git 的 insteadOf 配置在某些情况下被忽略。
具体来说,当 go get 尝试获取模块时,它会先向模块代理发送请求,如果代理返回 404 或 410 错误,它会回退到直接使用版本控制系统(如 Git)获取。但在回退时,Go 工具链会使用内置的 HTTP 客户端,而不是直接调用 Git 命令,因此 Git 的 insteadOf 配置不会生效。
要解决这个问题,你可以使用 Go 模块的 GOPRIVATE 环境变量来指定私有模块,并配置 GIT_TERMINAL_PROMPT 或 GIT_SSH 环境变量来强制使用 SSH 协议。以下是示例代码:
// 设置环境变量
export GOPRIVATE=bitbucket.org/organizationname
export GIT_TERMINAL_PROMPT=1
// 或者使用自定义 SSH 命令
export GIT_SSH=/path/to/ssh-custom-script
另外,你可以在 ~/.gitconfig 或项目中的 .git/config 文件中显式配置 SSH URL:
[url "git@bitbucket.org:"]
pushInsteadOf = https://bitbucket.org/
insteadOf = https://bitbucket.org/
如果问题仍然存在,可以尝试升级到 Go 1.17 或更高版本,因为后续版本对私有模块的支持有所改进。同时,确保你的 go env 配置正确,特别是 GOPRIVATE 和 GONOSUMDB 设置:
go env -w GOPRIVATE=bitbucket.org/organizationname
go env -w GONOSUMDB=bitbucket.org/organizationname
最后,如果模块是私有的,确保在 go.mod 文件中正确声明了模块路径,并且 Bitbucket 仓库的访问权限已配置 SSH 密钥。


