Golang中"go get"获取最新版本但不符合所需版本的问题

Golang中"go get"获取最新版本但不符合所需版本的问题 我开发了一个名为 abc 的包,它存储在一个私有的 GitLab 实例中。该包的最新版本已导入我的程序,并且运行正常。最近,我需要对这个包进行一些修改,我原以为可以创建一个新的分支 f1,并通过获取特定的分支/版本来测试包 abc,操作如下:

$ GOPRIVATE="gitlabprivate.com" go mod edit -require gitlabprivate.com/workspace/abc@f1
$ GOPRIVATE="gitlabprivate.com" go get -u 

然而,这失败了,并出现以下错误:

abc at latest version v0.0.0-20200407120314-666552805e7a but not at required version v0.0.0-20200416000117-e07f205569a2

其中 666552805e7a 是 master/最新版本。我需要的版本/分支 e07f205569a2 已经下载到我的模块路径中,但我的程序无法使用它。

我该如何解决这个问题?更重要的是,处理本地开发的包的正确流程是什么?


更多关于Golang中"go get"获取最新版本但不符合所需版本的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

我明白您的意思,但 f1 实际上基于 master 分支,并且包含了最新的提交。

我还尝试了移除 go.mod 中的条目并直接运行 go get

$ GOPRIVATE="gitlabprivate.com" go get gitlabprivate.com/workspace/abc@f1

我认为这应该能消除关于 latest 是什么的疑虑,但它导致了相同的错误。我现在很困惑,为什么它甚至知道版本 666552805e7a

更多关于Golang中"go get"获取最新版本但不符合所需版本的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


kaizencoder:

我现在很困惑,为什么它甚至能感知到版本 666552805e7a

你需要检查 gocache,看看下载的 git 分支是否与你的主仓库完全相同。据我理解,666552805e7a 是 go mod 的伪版本号,通常仅仅盯着看是没什么意义的。

对我来说,你的 f1 就相当于我上下文中的 release-vX-Y-Z。它是你软件的一个固定版本。go get 会原样获取那个分支。我的意思是,如果你想要最新、最前沿的版本,你可能需要相应地安排分支管理。所以,在我的上下文中,我会使用 go get @next 来获取最前沿的版本。


别担心,我仍然在 go get 时使用发布分支而不是标签,因为 v2, v3, ..., vN 目录强制策略确实把仓库搞得一团糟。

如何让它工作,更重要的是,使用本地开发包的正确流程是什么?

关键在于你的 require 命令是要求 go 模块获取 f1 分支,而不是最新版本、提交 ID、标签 ID 或其他包含最新版本的分支(例如 master?)。如果你将 f1 分支更新到最新状态,它应该能够获取到最新的提交 ID。

这更多取决于你如何管理你的仓库结构。你可以遵循 Debian 的交付实践:

  1. master = stable 稳定版。
  2. staging = test 测试版(用于下一个 stable 稳定版)
  3. next = sid 版(前沿版本)
  4. release-vX-Y-Z = 通过分支获取的特定版本发布

在Go模块中,当需要测试特定分支或本地修改时,正确的做法是使用replace指令。以下是解决方案:

1. 使用replace指令覆盖导入路径

在你的go.mod文件中添加replace指令,将包的导入路径指向本地开发目录或特定分支:

module yourproject

go 1.21

require (
    gitlabprivate.com/workspace/abc v0.0.0-20200407120314-666552805e7a
)

replace gitlabprivate.com/workspace/abc => ../path/to/local/abc

或者指向远程分支:

replace gitlabprivate.com/workspace/abc => gitlabprivate.com/workspace/abc@f1

2. 完整的工作流程示例

# 1. 克隆你的包到本地
$ cd /path/to/workspace
$ git clone git@gitlabprivate.com:workspace/abc.git
$ cd abc
$ git checkout f1

# 2. 在你的主项目中修改go.mod
$ cd /path/to/yourproject
$ go mod edit -replace gitlabprivate.com/workspace/abc=/path/to/workspace/abc

# 3. 更新依赖
$ go mod tidy

# 4. 验证替换是否生效
$ go list -m all | grep abc

3. 使用go work进行多模块开发(Go 1.18+)

对于更复杂的本地开发场景,可以使用Go Workspace:

# 1. 创建工作区
$ cd /path/to/workspace
$ go work init
$ go work use ./yourproject
$ go work use ./abc

# 2. 在workspace目录下工作
$ cd /path/to/workspace
$ go run ./yourproject

4. 处理私有仓库的认证

确保你的Git配置能访问私有仓库:

# 配置Git使用SSH
$ git config --global url."git@gitlabprivate.com:".insteadOf "https://gitlabprivate.com/"

# 或者设置环境变量
$ export GOPRIVATE=gitlabprivate.com
$ export GONOSUMDB=gitlabprivate.com

5. 清理和恢复

测试完成后,移除replace指令:

$ go mod edit -dropreplace gitlabprivate.com/workspace/abc
$ go mod tidy

对于本地包开发,推荐使用replace指令指向本地路径,这样可以直接测试修改而无需每次提交到远程仓库。使用Go Workspace可以进一步简化多模块开发流程。

回到顶部