首页 > 解决方案 > 为什么 go get -u 在模块目录中需要很长时间,但在 golang 中却很快完成?

问题描述

我有一个非常缓慢且不稳定的网络。

在本地运行的第一次观察

例如,当我go get -u github.com/jinzhu/gorm在一个新的模块目录(其中有 main.go)中运行时。它会打印出很多行,并且由于网络缓慢且不稳定,在我的本地环境中永远无法成功完成。

但是如果我在模块目录之外运行相同的命令,它可以在合理的时间内完成而无需任何标准输出。

远程运行的第二次观察

我有一个位于美国的远程 VPS 服务器。我在那里创建了相同的模块目录并在 remote: 上的模块内运行相同的命令go get -u github.com/jinzhu/gorm,并且go.mod将具有以下内容:

require (
    cloud.google.com/go v0.39.0 // indirect
    github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 // indirect
    github.com/golang/mock v1.3.1 // indirect
    github.com/google/btree v1.0.0 // indirect
    github.com/google/pprof v0.0.0-20190515194954-54271f7e092f // indirect
    github.com/jinzhu/gorm v1.9.8 // indirect
    github.com/jinzhu/inflection v0.0.0-20190603042836-f5c5f50e6090 // indirect
    github.com/kr/pty v1.1.4 // indirect
    github.com/lib/pq v1.1.1 // indirect
    go.opencensus.io v0.22.0 // indirect
    golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 // indirect
    golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 // indirect
    golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff // indirect
    golang.org/x/lint v0.0.0-20190409202823-959b441ac422 // indirect
    golang.org/x/mobile v0.0.0-20190509164839-32b2708ab171 // indirect
    golang.org/x/mod v0.1.0 // indirect
    golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect
    golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0 // indirect
    golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect
    golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
    golang.org/x/tools v0.0.0-20190603152906-08e0b306e832 // indirect
    google.golang.org/appengine v1.6.0 // indirect
    google.golang.org/genproto v0.0.0-20190530194941-fb225487d101 // indirect
    google.golang.org/grpc v1.21.0 // indirect
    honnef.co/go/tools v0.0.0-20190602125119-5a4a2f4a438d // indirect
)

然后我运行go mod tidygo.mod变成:

require (
    cloud.google.com/go v0.39.0 // indirect
    github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3 // indirect
    github.com/google/go-cmp v0.3.0 // indirect
    github.com/jinzhu/gorm v1.9.8
    github.com/jinzhu/inflection v0.0.0-20190603042836-f5c5f50e6090 // indirect
    github.com/lib/pq v1.1.1 // indirect
    golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 // indirect
    google.golang.org/appengine v1.6.0 // indirect
)

但是如果我完全删除该require(...)部分go.mod然后执行go mod tidy,我会得到以下内容go.mod

require github.com/jinzhu/gorm v1.9.8

只需要一个。并且通过这一行,我运行go build,模块可以构建并成功运行,没有任何问题。

所以我很困惑go get -u在我的模块目录中真正做了什么。

我的两个问题:

我正在使用最新的稳定 golang go1.12.5。因为go get -u电话gitgit电话curl,但curl在不稳定的网络上很糟糕(相比wget)。我无法go get -u在模块目录中完成。我会得到很多error: RPC failed; The remote end hung up unexpectedly; fatal: early EOF; fatal: index-pack failed;。我不知道是否有解决此问题的方法。但是我可以go get -u在模块目录之外使用。

(顺便说一句,如果go get可以使用wget,它可以在我的本地环境中使用。我使用wget从来没有任何问题,wget在等待很长时间后终于完成下载。但不幸的是,wget不是当前开发人员的首选工具世界)。

标签: go

解决方案


我应该在模块目录内运行 go get -u 还是可以简单地在模块目录外运行它?

如果您正在使用模块,如果您希望它实际更新您的go.mod/go.sum文件,则需要在模块目录中运行它。

为什么模块目录外的 go get -u 可以轻松完成?与在模块目录中运行相比,它是否执行相同的下载/升级?

他们的行为完全不同。go help getgo help module-get并且go help modules应该解释一些差异,并在您的情况下检查模块文档

一个常见的错误是认为 go get -u foo 只获取最新版本的 foo。实际上,go get -u foo 或 go get -u foo@latest 中的 -u 意味着还获取 foo 的所有直接和间接依赖项的最新版本。

go.mod 的 go.mod 包含很多东西(https://github.com/jinzhu/gorm/blob/master/go.mod),包括它支持的每个可能的数据库的驱动程序,这看起来非常激烈。由于您只是在做一个毯子-u而不是指定@v1.9.3或其他任何内容,因此它正在尝试以模块感知模式更新 Gorm 的所有依赖项(以及依赖项的依赖项!)。


推荐阅读