New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: go get -u=patch with argument bumps minor version #26812

Open
mfridman opened this Issue Aug 5, 2018 · 3 comments

Comments

Projects
None yet
6 participants
@mfridman

mfridman commented Aug 5, 2018

What version of Go are you using (go version)?

go version devel +5a720d229d Sat Aug 4 16:37:47 2018 +0000 darwin/amd64

Does this issue reproduce with the latest release?

N/A, building from source

What did you do?

Repro provided.

$ git clone git@github.com:mfridman/srfax.git
$ cd srfax

$ cat go.mod 
module github.com/mfridman/srfax

require (
	github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699
	github.com/pkg/errors v0.6.0
)


$ go get -u=patch
$ git diff
# no changes

$ go get -u=patch github.com/pkg/errors
$ git diff
-       github.com/pkg/errors v0.6.0
+       github.com/pkg/errors v0.8.0

Based on the docs, I was expecting pkg/errors to remain on v0.6.0, but instead it got bumped to v0.8.0. Running go get -u=patch (without arg) did not update the patch version.

The -u=patch flag (not -u patch) instructs get to update dependencies to use newer patch releases when available

I would only ever expect the minor version to be bumped when running go get -u or go get -u github.com/pkg/errors.

Likewise I would expect -u=patch with or without an arg to operate in the same way.

@gopherbot, please add label modules

@gopherbot gopherbot added the modules label Aug 5, 2018

@FiloSottile FiloSottile added this to the Go1.11 milestone Aug 6, 2018

@rsc

This comment has been minimized.

Contributor

rsc commented Aug 9, 2018

The documentation explains this:

The first step is to resolve which dependencies to add.

For each named package or package pattern, get must decide which version of
the corresponding module to use. By default, get chooses the latest tagged
release version, such as v0.4.5 or v1.2.3. If there are no tagged release
versions, get chooses the latest tagged prerelease version, such as
v0.0.1-pre1. If there are no tagged versions at all, get chooses the latest
known commit.

This default version selection can be overridden by adding an @version
suffix to the package argument, as in 'go get golang.org/x/text@v0.3.0'.
For modules stored in source control repositories, the version suffix can
also be a commit hash, branch identifier, or other syntax known to the
source control system, as in 'go get golang.org/x/text@master'.
The version suffix @latest explicitly requests the default behavior
described above.

If a module under consideration is already a dependency of the current
development module, then get will update the required version.
Specifying a version earlier than the current required version is valid and
downgrades the dependency. The version suffix @none indicates that the
dependency should be removed entirely.

Although get defaults to using the latest version of the module containing
a named package, it does not use the latest version of that module's
dependencies. Instead it prefers to use the specific dependency versions
requested by that module. For example, if the latest A requires module
B v1.2.3, while B v1.2.4 and v1.3.1 are also available, then 'go get A'
will use the latest A but then use B v1.2.3, as requested by A. (If there
are competing requirements for a particular module, then 'go get' resolves
those requirements by taking the maximum requested version.)

The -u flag instructs get to update dependencies to use newer minor or
patch releases when available. Continuing the previous example,
'go get -u A' will use the latest A with B v1.3.1 (not B v1.2.3).

The -u=patch flag (not -u patch) instructs get to update dependencies
to use newer patch releases when available. Continuing the previous example,
'go get -u=patch A' will use the latest A with B v1.2.4 (not B v1.2.3).

By saying github.com/pkg/errors on the command line you are implicitly saying github.com/pkg/errors@latest. The -u=patch applies to dependencies of the listed packages/modules, not to those packages/modules themselves.

Maybe we can revisit semantics for Go 1.12 but these are the Go 1.11 semantics.

@rsc rsc modified the milestones: Go1.11, Go1.12 Aug 9, 2018

@rsc rsc added the NeedsDecision label Aug 9, 2018

@stevenh

This comment has been minimized.

Contributor

stevenh commented Oct 19, 2018

I would agree with the original poster, that this behaviour is very confusing, even reading the docs several times its wasn't clear and caused much hair pulling and time wasted.

I believe the reason for this is that it states dependencies and if you running go -u get <package> in your repo <package> is a dependency.

The use case IMO for running go get -u=patch <package> is to update just <package> and its dependencies using the patch strategy.

With the current design there is no easy way to update a specific package and its dependencies using the patch strategy. The only option is to manually visit to the repo site look for the version and issue the manual go get -u=patch <package>@vX.Y.Z which is a royal PITA.

@bcmills

This comment has been minimized.

Member

bcmills commented Nov 13, 2018

go get -u=patch some/binary@latest has a pretty clear use-case: you want to build and install the latest version of some/binary@latest, using the patch releases of its dependencies. After #24250 is addressed, that may well be the best default for installing tools from outside of a module. On the other hand, outside of a module, some/binary and some/binary@latest resolve to the same version anyway: perhaps we should only implicitly add @latest to new dependencies rather than existing ones, uniformly.

There is also a bit of a skew between the old and new go get behaviors without -u: in GOPATH mode, go get foo for some package foo already in GOPATH/src does not upgrade the version, but in module mode it implicitly upgrades to @latest.

That provides an opportunity for a nice symmetry: if the @latest version is necessary to upgrade the named package to the latest version, then we could add a similar version @patch, with the meaning “the latest patch release of the minor version already in the module graph”.

I don't think we'll get to this for 1.12, but I'd like to at least make a decision on it early in 1.13

@bcmills bcmills modified the milestones: Go1.12, Go1.13 Nov 13, 2018

@rsc rsc added early-in-cycle and removed modules labels Nov 20, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment