去更新所有模块

以此模块为例(使用特定的提交,以便其他人可以看到 我所看到的) :

git clone git://github.com/walles/moar
Set-Location moar
git checkout d24acdbf

我想一个方法来告诉去“更新一切”。假设模块 将与最新版本的一切。以下是我发现的五种方法 这样做,假设每一个都在一个干净的克隆上运行,结果是 go.mod为19 电话:

go get -u

这样就产生了14行的 go.mod:

go get -u
go mod tidy

这样就产生了一个包含13行的 go.mod:

go mod tidy

如果我只是手动删除 require中的所有内容并运行 go mod tidy,我得到 12行。如果我只是手动删除 require中的所有内容并运行 go get -u,我将得到11行。我的问题是,为什么这些方法会产生不同的 结果,什么是“正确的方法”来做我正在尝试做的事情?

106922 次浏览

tl;dr;

this is what you want:

go get -u
go mod tidy

and to recursively update packages in any subdirectories:

go get -u ./...

The inconsistencies you are seeing is due to the inherent organic nature of software.

Using your example, commit d24acdbf of git://github.com/walles/moar most likely was checked in by the maintainer without running go mod tidy (explaining the longer 19 lines). If the maintainer had, then you would see the 13 line version you see at the end.

go get -u on it's own is more aggressive in pulling in dependencies. Also, the mere fact of updating dependencies to their latest (compatible) version, may in & of itself pull in new direct/indirect dependencies. These dependencies may grow even further if you tried this tomorrow (the latest version of some sub-dependency adds new functionality, so it needs new dependencies). So there may be a valid reason the repo maintainer fixes at a particular (non-latest) version.

go mod tidy cleans up this aggressive dependency analysis.

P.S. It's a common misconception that dependencies will shrink after go mod tidy: tracking go.sum, in some cases this file will grow after a tidy (though, not in this case)

Run go get -u && go mod tidy 1

More details:

  • go get -u (same as go get -u .) updates the package in the current directory, hence the module that provides that package, and its dependencies to the newer minor or patch releases when available. In typical projects, running this in the module root is enough, as it likely imports everything else.

  • go get -u ./... will expand to all packages rooted in the current directory, which effectively also updates everything (all modules that provide those packages).

  • Following from the above, go get -u ./foo/... will update everything that is rooted in ./foo

  • go get -u all updates everything including test dependencies; from Package List and Patterns

When using modules, all expands to all packages in the main module and their dependencies, including dependencies needed by tests of any of those.

go get will also add to the go.mod file the require directives for dependencies that were just updated.

  • go mod tidy makes sure go.mod matches the source code in the module. In your project it results in 12 lines because those are the bare minimum to match the source code.

  • go mod tidy will prune ABC1 and go.mod by removing the unnecessary checksums and transitive dependencies (e.g. // indirect), that were added to by go get -u due to newer semver available. It may also add missing entries to go.sum.


Note that starting from Go 1.17, newly-added indirect dependencies in go.mod are arranged in a separate require block.


1: updates dependencies' newest minor/patch versions, go.mod, go.sum