Search code examples
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 [email protected]:.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.

  • If there is a way to use git tag versioning in local module packages, I am OK to use local replace in go.mod instead of configuring a private ssh repo.

  • If the above point is not possible, how to avoid https fetch when I configure a private ssh repo? I think ssh repo has nothing to do with https protocol.


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://[email protected]"]
        insteadOf = https://private.com
    

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

    [url "[email protected]:"]
        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.