Explain exclude and retract. Who writes each one, and how do they affect version selection?
exclude is written by a consumer in the main module. It forbids one specific version. If something requires an excluded version, MVS moves up to the next higher non-excluded version (not down). Like replace, it is ignored in dependencies.
retract (Go 1.16+) is written by the module author in the module's own go.mod. It marks versions that were published by mistake or are dangerous. The go.mod change has to be published in a newer version, because tags are immutable and proxies cache them forever.
// in example.com/lib go.mod, released as v1.5.1
retract (
v1.5.0 // leaked credentials in testdata
[v1.3.0, v1.3.9] // data-corruption bug
)
exclude example.com/other v0.9.2 // consumer-side only
Effects of retraction: go get example.com/lib@latest and go list -m -versions skip retracted versions. go list -m -u all warns about them. Builds that already depend on a retracted version keep working. Nothing breaks, you just get warnings.
A well-known trick: to retract a mistaken v1.0.0 when no fixed version exists yet, publish v1.0.1 whose go.mod retracts both v1.0.0 and v1.0.1.
More on Modules, Packages & Tooling
- Q410How do you release v2 of a module? Compare the "major branch" and "major subdirectory" strategies, and explain +incompatible.
- Q411When would you use a replace directive, and why doesn't a dependency's replace affect your build?
- Q413What is a pseudo-version, and when does the go command generate one?
- Q414What problem do Go workspaces (go.work) solve? How do they differ from replace?
- Q415How does vendoring work in module mode, and when is it still worth using?
- Q416How do internal packages work? Give an example of an allowed and a forbidden import.