Because in Go 1.17 the module graph has been changed to enable pruning and lazy loading. The second require
block contains indirect dependencies.
https://golang.org/doc/go1.17#go-command
If a module specifies go 1.17 or higher, the module graph includes only the immediate dependencies of other go 1.17 modules, not their full transitive dependencies. […]
[…] If a module specifies go 1.17 or higher in its go.mod file, its go.mod file now contains an explicit require directive for every module that provides a transitively-imported package. (In previous versions, the go.mod file typically only included explicit requirements for directly-imported packages.)
Because the number of explicit requirements may be substantially larger in an expanded Go 1.17 go.mod file, the newly-added requirements on indirect dependencies in a go 1.17 module are maintained in a separate require block from the block containing direct dependencies.
Note: the go.mod
file that you posted in your question has //indirect
dependencies in the first require block. I suspect, based on the wording “newly-added” in the quoted docs, that this is because those //indirect
dependencies were already listed there and go mod tidy
doesn’t rearrange them. If you:
- manually delete one of those
- and/or recreate the
go.mod
file with Go version set to1.17
or higher - and/or run
go mod tidy -go=1.17
then it will separate direct and //indirect
dependencies in the two blocks. Anyway, this is a visual convenience, the documentation doesn’t mandate creation of two separate blocks.
Additional references:
-
graph pruning: https://go.dev/ref/mod#graph-pruning
-
behaviors dependent on
go.mod
‘sgo
directive: https://go.dev/ref/mod#go-mod-file-go