This is a Go 1.16 issue which is currently investigated in golang/go
issue 44529
It includes Jay Conrod's comment:
go mod tidy
and go get
may both hit the network to look up imported packages that aren't provided by any required module.
If a module is replace locally, the go command will look there first, but I think it may still go out to the network for other prefixes of the module path.
Instead, you can add a requirement on a non-existent version while replacing that version:
go mod edit -require example.com/[email protected] -replace example.com/[email protected]=../local
Adding a replacement, even one without a version on the left side, doesn't automatically add that module to the build list.
If it did, the go
command would read its go.mod
file and apply its requirements. That could influence selected versions of other modules, even if the replaced module didn't provide any packages.
Bryan C. Mills from Google adds:
go mod tidy
should never do a network lookup if it could add a replaced module instead. (see import.go#queryImp()
)
go get
, on the other hand, will perform a network lookup in order to identify the true latest version, taking your replacements into account (query.go#Versions()
), and then that version will be replaced instead of downloaded.
It does that so that the latest version added by go get is always consistent with go list -m [⋯]@latest
, and so that (if possible) your require directive always specifies a valid version for downstream consumers (if any), so that they won't break when they require your module. (Downstream consumers will not pick up your replace directives, so they need a valid version.)
If you are not using a proxy for the repo in question, that lookup may involve cloning the upstream repo. So that can be a pretty expensive operation. (Note that the official distributions of the go command use proxy.golang.org
by default, but the Fedora fork of the go
command does not.)
If that network lookup fails, then go get
will also fall back to replacement version (query.go#Latest()
)