290

Starting with v1.11 Go added support for modules. Commands

go mod init <package name>
go build

would generate go.mod and go.sum files that contain all found versions for the package dependencies. If a module does not have any releases, the latest commit of that module is used. If a module does have releases, the latest one is picked as a dependency.

However sometimes I would need functionality that is not in a published release yet, but from a commit made after that release. How do I set go.mod to point not to a release of a module, but to a specific commit in the module's repository? It looks like I can do it by hand in go.mod with

module /my/module
    
require (
    ...
    github.com/someone/some_module v0.0.0-20181121201909-af044c0995fe
    ...
)

where v0.0.0 does not correspond to the last published release tag, 20181121201909 would be a commit timestamp and af044c0995fe would be the commit hash? Should such information to be found and entered by hand, or there is a better way?

8 Answers 8

405

Just 'go get' at the commit hash you want:

go get github.com/someone/some_module@af044c0995fe

'go get' will correctly update the dependency files (go.mod, go.sum).

More information: https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies

Sign up to request clarification or add additional context in comments.

7 Comments

In case getting error "unknown revision" or "invalid version" - Make sure that you did not specify hash of PR (pull request). Even a merged PR might be wrong. Look for the commit hash in the repo under /commits, but not under /pulls. See more info here: golang/go#31191 explicitly filters out these kind of commits.
the OP askes how to add it to go.mod file , not how to do a go get
@Nulik go get is the correct way to update/add-to go.mod in the way the OP asked.
Note that you can also specify a branch or tag name instead of a commit hash.
@cambraca you cant use the branch name if it's past v1 or you will get invalid version: go.mod has post-v1 module path
|
201

In addition the answer from Everton on using go get github.com/someone/some_module@af044c0995fe to get a specific commit, you can also use branch names such as:

  • go get github.com/someone/some_module@master
  • go get github.com/someone/some_module@dev_branch

Those examples get the latest commit on the corresponding branch.

It will still be recorded as a pseudo-version in your go.mod file, such as v0.0.0-20171006230638-a6e239ea1c69. (This helps provide a simple total ordering across all versions based on standard semver ordering).

5 Comments

thanks for the pseudo-version explanation. i was trying to do a replace to use a temporary fork of some dependency, but could not find a way to make that replacement to point to some commit. Had to create a version tag and specify it like this replace github.com/original/somelib => github.com/fork/somelib v1.2.3, which is a bit too much when i just want to quickly test stuff. replace github.com/original/somelib => github.com/fork/somelib@commithash and replace github.com/original/somelib => github.com/fork/somelib commithash do not work
1. push your code to github.com/fork/somelib @ dev branch 2. modify your go.mod file, add a line replace github.com/original/somelib => github.com/fork/somelib dev 3. execute go mod tidy command. After done these, go will auto replace the dev in go.mod to a suitiable pseudo-version.
you cant use the branch name if it's past v1 or you will get invalid version: go.mod has post-v1 module path
The @dev_branch doesn't work if the branch name contains slashes.
Like mentioned by @hookenz, branch with slashes don't work, in those case use the full commit + go mod tidy: ... => github.com/<org>/<name> b5906304132ae4379efd349040df095e555ba5b7 of said branch
41

If you want to temporarily substitute a dependency to a local directory (for example if you work on 2 modules sumultaneously) you can add replace statement at the end of go.mod file:

module example.com/mypkg

go 1.15

require (
  gitlab.com/someone/a_package v0.14.2
)

replace gitlab.com/someone/a_package => ../my_forks/a_package

2 Comments

The question is asking about latest commit in a remote repo, not a local checked-out state.
Thank you. I was trying to test a project with a remote module branch because I didn´t know it was possible to target a local directory.
32

I have been banging my head for some time that how it works for everyone and I am not able to run it. For me, I had to commit to master branch then only I was able to get it.

For go get to work with specific branch, commit id or tag, you need to enable a flag for go module by running below command

go env -w GO111MODULE=on

after this we will be able to do

go get repo@branchname
go get repo@tag
go get repo@commithash

Comments

28

Also if you put the word latest in place of the tag in the go.mod file it will get changed to the latest tag the modules.

For example:

module /my/module

require (
...
github.com/someone/some_module latest
...
)

will become

module /my/module

require (
...
github.com/someone/some_module v2.0.39
...
)

after running go mod tidy

1 Comment

That's probably the easiest!
14
  • Download source from branch
    go get your-repo@branch-name read output with go module version to be added to require or replace:
    go: downloading github.com/your-repo v1.2.3-0.20210609123456-123123123
  • Later this version can be found as output string of the following command
    go list -m -json your-repo@branch-name | jq '.|"\(.Path) \(.Version)"'
  • If jq is not installed on your PC - manually combine Path and Version values of result from:
    go list -m -json your-repo@branch-name
    separated by space:
    your-repository v1.2.3-0.20210609123456-123123123

2 Comments

I got the following error: malformed module path "foo/bar": missing dot in first path element for the command: go list -m -json foo/bar@main
@Dentrax Try something like go list -m -json github.com/foo/bar@main
3

If you want a commit from the current tip, a very simple solution is to run

go get github.com/someone/some_module@master

(or whatever branch is wanted).

This will pull the right timestamp and commit hash into go.mod.

Comments

1

to get the branchname you need to do it like that:
GOPROXY=direct go get -u github.com/someone/some-repo@branch-name

if you don't want to type it all the time you can do it like that permanently:
go env -w GOPROXY=direct

and then you can update just by:
go get github.com/someone/some-repo@branch-name

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.