go get using ssh instead of https (NOT on github)

Viewed 11328

We have a private code repository accessible only through ssh/git (no https), and we would like to host our go code/modules there.

First I tried:

git config --global url."git@code.internal.local:".insteadOf "https://code.internal.local/"

so, both of the following work just fine:

  • git clone git@code.internal.local:reponame.git
  • git clone https://code.internal.local/reponame

But go get code.internal.local/reponame fails, as go still insists on trying https://... not git.

package code.internal.local/reponame: unrecognized import path "code.internal.local/reponame": https fetch: Get "https://code.internal.local/reponame?go-get=1": dial tcp 192.168.0.5:443: i/o timeout
3 Answers

I checked my .gitconfig and found this (for github private repo) -

[url "ssh://git@github.com/"]
        insteadOf = https://github.com/

above configuration is working for me. Also you can try creating a .netrc file in your project root, but that should not be pushed to remote code repo.

The problem

The behaviour you're observing is detailed in the section "Remote import paths" of the go get documentation. In particular, just by looking at the remote import path code.internal.local/reponame, go get has no way to know which VCS and at which URL in particular is used to actually host that package.

To solve that problem, go get employs a set of HTTPS (and HTTP, as a fallback, which has to be explicitly enabled) GET requests to a set of special URLs constructed out of the specified import path. It is assumed that whatever serves such calls is able to respond with a reply which identifies the VCS to use and the URL of the repository.

Possible solutions

If you're using modules, you might set up a dedicated "module proxy" wherever is convenient for your team (also, there may be deployed many proxies) and make the team members use the GOPROXY environment variable which points at the convenient instance. See go help modules for more info.

Otherwise, if you can put a webserver to answer remote import path resolution requests, you can do that; nginx and apache can be used for that just with their stock modules.

Otherwise you might need to resort to manual operation.

I posted a detail answer here https://stackoverflow.com/a/65925691/348719

Basically, you should add .git suffix to require at client and module at server. Without .git suffix, go get will use https.

  • At client (go.mod) (change the version number to correct one):
require code.internal.local/reponame.git v0.1.0

And it's better add go env -w GOPRIVATE=code.internal.local

  • At server (go.mod)
module code.internal.local/reponame.git
Related