如何将 go.mod 中的 Go 模块依赖项指向 repo 中的最新提交?

Posted

技术标签:

【中文标题】如何将 go.mod 中的 Go 模块依赖项指向 repo 中的最新提交?【英文标题】:How to point Go module dependency in go.mod to a latest commit in a repo? 【发布时间】:2019-05-09 23:17:48 【问题描述】:

从 v1.11 开始,Go 添加了对模块的支持。命令

go mod init <package name>
go build

将生成包含所有找到的包依赖项版本的 go.modgo.sum 文件。

如果一个模块没有任何版本,则使用该模块的最新提交。如果一个模块确实有发布,则选择最新的作为依赖项。

但是,有时我需要尚未发布的版本中的功能,而是来自该版本之后所做的提交。如何将go.mod 设置为不指向模块的发布,而是指向模块存储库中的特定提交?

看起来我可以在 go.mod 中手动完成

module /my/module

require (
...
github.com/someone/some_module v0.0.0-20181121201909-af044c0995fe
...
)

其中v0.0.0 不对应于最后发布的发布标签,20181121201909 将是提交时间戳af044c0995fe 将是提交哈希?是否应该手动查找和输入这些信息,还是有更好的方法?

【问题讨论】:

【参考方案1】:

只需“获取”您想要的提交哈希:

go get github.com/someone/some_module@af044c0995fe

'go get' 将正确更新依赖文件(go.mod、go.sum)。

更多信息:https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies

【讨论】:

如果出现错误“unknown revision”或“invalid version” - 请确保您没有指定 PR 的哈希值(拉取请求)。即使是合并的 PR 也可能是错误的。在/commits 下的repo 中查找提交哈希,但不在/pulls 下。在此处查看更多信息:golang/go#31191 明确过滤掉此类提交。 OP 询问如何将其添加到 go.mod 文件中,而不是如何执行 go get @Nulik go get 是按照 OP 要求的方式更新/添加到 go.mod 的正确方法。 请注意,您还可以指定分支或标签名称而不是提交哈希。 @cambraca 如果分支名称已超过 v1,您将无法使用分支名称,否则您将获得 invalid version: go.mod has post-v1 module path【参考方案2】:

除了来自埃弗顿的answer 使用go get github.com/someone/some_module@af044c0995fe 来获取特定的提交,您还可以使用分支名称,例如:

go get github.com/someone/some_module@master go get github.com/someone/some_module@dev_branch

这些示例在相应分支上获得最新提交。

它仍会在您的go.mod 文件中记录为pseudo-version,例如v0.0.0-20171006230638-a6e239ea1c69。 (这有助于基于标准 semver 排序在所有版本中提供简单的总排序)。

【讨论】:

感谢伪版本的解释。我试图做一个replace 来使用某个依赖项的临时分支,但找不到一种方法来使该替换指向某个提交。必须创建一个版本标签并像这样指定它replace github.com/original/somelib =&gt; github.com/fork/somelib v1.2.3,当我只想快速测试东西时,这有点太多了。 replace github.com/original/somelib =&gt; github.com/fork/somelib@commithashreplace github.com/original/somelib =&gt; github.com/fork/somelib commithash 不起作用 1. push你的代码到github.com/fork/somelib@@dev分支 2.修改你的go.mod文件,添加一行replace github.com/original/somelib =&gt; github.com/fork/somelib dev 3.执行go mod tidy命令。完成这些后,go 会自动将 go.mod 中的 dev 替换为合适的伪版本。 如果分支名称超过 v1,则不能使用分支名称,否则您将得到 invalid version: go.mod has post-v1 module path【参考方案3】:

一段时间以来,我一直在思考它如何适用于每个人,但我无法运行它。对我来说,我必须提交到 master 分支,然后只有我能够得到它。

要让 go get 使用特定的分支、提交 id 或标签,您需要通过运行以下命令来启用 go 模块的标志

去 env -w GO111MODULE=on

在这之后,我们将能够做到

go get repo@branchname
go get repo@tag
go get repo@commithash

【讨论】:

【参考方案4】:

如果您想暂时将依赖项替换为本地目录(例如,如果您同时处理 2 个模块),您可以在 go.mod 文件的末尾添加 replace 语句:

module example.com/mypkg

go 1.15

require (
  gitlab.com/someone/a_package v0.14.2
)

replace gitlab.com/someone/a_package => ../my_forks/a_package

【讨论】:

【参考方案5】:

此外,如果您在 go.mod 文件中将单词 latest 代替标签,它将被更改为模块的最新标签。

例如:

module /my/module

require (
...
github.com/someone/some_module latest
...
)

会变成

module /my/module

require (
...
github.com/someone/some_module v2.0.39
...
)

运行后go mod tidy

【讨论】:

【参考方案6】: 从分支下载源码go get your-repo@branch-name 使用要添加到 requirereplace 的 go 模块版本读取输出: 去:下载 github.com/your-repo v1.2.3-0.20210609123456-123123123 稍后此版本可以作为以下命令的输出字符串找到go list -m -json your-repo@branch-name | jq '.|"\(.Path) \(.Version)"' 如果您的 PC 上未安装 jq - 手动组合 PathVersion 的结果值来自:go list -m -json your-repo@branch-name 以空格分隔:your-repository v1.2.3-0.20210609123456-123123123

【讨论】:

以上是关于如何将 go.mod 中的 Go 模块依赖项指向 repo 中的最新提交?的主要内容,如果未能解决你的问题,请参考以下文章

使用go mod下载时导致“模式匹配无模块依赖”的原因是什么?

go mod使用

当***模块及其子模块之一作为单独版本单独导入时,如何解决冲突的 go 模块依赖关系?

go mod 相关的八个命令

go mod

Go语言 go mod 使用方法