gogo-modules

Why does go module ssh custom private repo (non-github) config still request https fetch?


I am using Go modules.

In order to use module version, I cannot use local module. For example:

replace locakpkg => ../localpkg v0.1.0

The above will fail because replacement local path cannot have version so far (go 1.15).

Thus, to make the module version work, I decided to use a private ssh repo.

I did search how to make private ssh repo work for two days.

By following many online articles, I did

git config --global url.user@private.com:.insteadOf https://private.com/
go env -w GOPRIVATE=private.com

I found out go get will always do https fetch to check ssl credential. So I configured a https server properly too.

But in the end, I still get an error message:

unrecognized import path "private.com/foo": reading https://private.com/foo?go-get=1: 404 Not Found

I did google this error and found out this spec https://golang.org/ref/mod#vcs-find which says I have to let the server reply with <meta name="go-import" content="root-path vcs repo-url"> for https fetch request.


Solution

  • (I am using go 1.15 at linux. The latest stable version while posting this answer)

    I solved the problem and posting here, hopefully, this will help other people one day. I don't find any correct answer by my search online.

    In short, the answer is to use .git suffix in all places. Without .git suffix, go mod tidy and go get will use https instead of ssh (git).

    At Client:

    The file ~/.gitconfig (at linux) if you use /repopath/foo.git path at server:

    [url "ssh://user@private.com"]
        insteadOf = https://private.com
    

    The file ~/.gitconfig (at linux) if you use ~/repopath/foo.git path at server:

    [url "user@private.com:"]
        insteadOf = https://private.com/
    

    Execute the following to update ~/.config/go/env at linux:

    go env -w GOPRIVATE=private.com
    

    In go.mod, it should use

    require private.com/repopath/foo.git v0.1.0
    

    In file.go, it should be

    import private.com/repopath/foo.git
    

    At SSH Server

    in foo.git/go.mod at private server should have:

    module private.com/repopath/foo.git
    

    And make sure the git repo at server has tag version v0.1.0. Don't forget to use git push --tags at client to update the tag version to the server. Without --tags, tag version will not be pushed.

    After adding .git suffix to all the required places, go mod tidy and go get will no longer send https request.