【问题标题】:What's the proper way to "go get" a private repository?“去获取”私有存储库的正确方法是什么?
【发布时间】:2020-06-20 10:52:51
【问题描述】:

经过多次谷歌尝试后,我正在寻找让$ go get 与私有存储库一起工作的方法。

第一次尝试:

$ go get -v gitlab.com/secmask/awserver-go
Fetching https://gitlab.com/secmask/awserver-go?go-get=1
https fetch failed.
Fetching http://gitlab.com/secmask/awserver-go?go-get=1
Parsing meta tags from http://gitlab.com/secmask/awserver-go?go-get=1 (status code 200)
import "gitlab.com/secmask/awserver-go": parse http://gitlab.com/secmask/awserver-go?go-get=1: no go-import meta tags
package gitlab.com/secmask/awserver-go: unrecognized import path "gitlab.com/secmask/awserver-go

是的,它没有看到元标记,因为我不知道如何提供登录信息。

第二次尝试:

关注https://gist.github.com/shurcooL/6927554。将配置添加到 .gitconfig。

[url "ssh://git@gitlab.com/"]
    insteadOf = https://gitlab.com/
$ go get -v gitlab.com/secmask/awserver-go --> not work
$ go get -v gitlab.com/secmask/awserver-go.git --> work but I got src/gitlab.com/secmask/awserer-go.git

是的,它可以工作,但使用带有我的项目名称的 .git 扩展名,我可以将其重命名为原始但每次都这样做 $ go get 不太好,还有其他方法吗?

【问题讨论】:

    标签: git go


    【解决方案1】:

    我在使用我们公司的 gitlab 上的私有存储库时遇到了 go get 的问题。 我花了几分钟试图找到解决方案。我确实找到了这个:

    1. 您需要通过以下地址获取私人令牌:
      https://gitlab.mycompany.com/profile/account

    2. 配置您的 git 以使用您的私有令牌添加额外的标头:

       $ git config --global http.extraheader "PRIVATE-TOKEN: YOUR_PRIVATE_TOKEN"
      
    3. 配置您的 git 以将请求从 http 转换为 ssh

       $ git config --global url."git@gitlab.mycompany.com:".insteadOf "https://gitlab.mycompany.com/"
      
    4. 终于可以正常使用go get了:

       $ go get gitlab.com/company/private_repo
      

    【讨论】:

    • http.extraheader 的有趣用法。 +1
    • 如果您使用许多 repo,--global 还会将您的私有令牌发送到其他 git 服务器吗?有什么安全风险吗?
    • 有人对此有任何评论吗?我认为当我们去访问它们时,它会将它发送到公共 github 存储库
    • 还有另一种选择,您可以仅将令牌发送到您的 gitlab - 但我不确定这是编码的。 git config --global url."https://${user}:${personal_access_token}@mygitlab.com".insteadOf "https://mygitlab.com"
    • 我认为@S.R 解决方案是最好的(尽管我必须在第一个 url 添加一个斜杠以使其适用于我的情况 => [...] url."https://${user}:${personal_access_token}@mygitlab.com/".insteadOf [...]
    【解决方案2】:

    对于独立/最终存储库,作为一种快速修复,为什么不使用您公司的域将 go.mod 中的模块命名为一个包...?

    module go.yourcompany.tld/the_repo
    

    go.yourcompany.tld 甚至不必作为有效(子)域存在...

    另外,在同一个go.mod 中,您可以使用replacement 块/行来使用以前以相同方式克隆的私有存储库(在$GOPATH/src/go.yourcompany.tld 中克隆的相应文件夹中)(为什么我们必须过分依赖在 GitHub 中?)

    编辑

    1. 不用说私人回购通常应该是私人回购,通常是标准的 git 回购,对吧?有了这个,为什么不只是在克隆文件夹中git clone 然后go get

    【讨论】:

      【解决方案3】:

      确保您删除了以前的 gitconfig,我遇到了同样的问题。

      之前我执行了gitconfig,其令牌已过期,下次使用新令牌执行命令时请务必删除前一个。

      【讨论】:

        【解决方案4】:

        在尝试了多种解决方案后,我的问题仍然存在。设置 ~/.netrc 和 SSH 配置文件后的最终解决方案是将以下行添加到我的 ~/.bash_profile

        export GOPRIVATE="github.com/[organization]"

        【讨论】:

          【解决方案5】:

          对于使用私有 GitLabs 的人,这里有一个可能有帮助的 sn-p:https://gist.github.com/MicahParks/1ba2b19c39d1e5fccc3e892837b10e21

          也贴在下面:

          问题

          go 命令行工具需要能够从您的私有 GitLab 获取依赖项,但需要进行身份验证。

          这假设您的私人 GitLab 托管在 privategitlab.company.com

          环境变量

          推荐使用以下环境变量:

          export GO111MODULE=on
          export GOPRIVATE=privategitlab.company.com
          

          以上几行可能最适合您的 shell 启动,例如 ~/.bashrc

          说明

          GO111MODULE=on 告诉 Golang 命令行工具你正在使用模块。我没有用不使用的项目对此进行测试 私有 GitLab 上的 Golang 模块。

          GOPRIVATE=privategitlab.company.com 告诉 Golang 命令行工具不要将公共互联网资源用于主机名 列出(如公共模块代理)。

          从您的私人 GitLab 获取个人访问令牌

          为了将来证明这些说明,请关注this guide from the GitLab docs。 我知道 Golang 命令行工具需要 read_api 范围才能工作,我可能怀疑 read_repository 为 好吧,但还没有证实这一点。

          设置~/.netrc

          为了让 Golang 命令行工具向 GitLab 进行身份验证,最好使用 ~/.netrc 文件。

          如果文件不存在,要创建文件,请运行以下命令:

          touch ~/.netrc
          chmod 600 ~/.netrc
          

          现在编辑文件的内容以匹配以下内容:

          machine privategitlab.company.com login USERNAME_HERE password TOKEN_HERE
          

          USERNAME_HERE 替换为您的 GitLab 用户名,TOKEN_HERE 替换为在 上一节。

          常见错误

          不要设置全局 git 配置,如下所示:

          git config --global url."git@privategitlab.company.com:".insteadOf "https://privategitlab.company.com"
          

          我相信在撰写本文时,Golang 命令行工具不完全支持 SSH git,这可能会导致 与~/.netrc 冲突。

          奖励:SSH 配置文件

          要经常使用git 工具,而不是Golang 命令行工具,最好设置~/.ssh/config 文件。 为此,请运行以下命令:

          mkdir ~/.ssh
          chmod 700 ~/.ssh
          touch ~/.ssh/config
          chmod 600 ~/.ssh/config
          

          请注意,以上文件和目录的权限是 SSH 在其默认配置下工作的必要条件 大多数 Linux 系统。

          然后,编辑~/.ssh/config 文件以匹配以下内容:

          Host privategitlab.company.com
            Hostname privategitlab.company.com
            User USERNAME_HERE
            IdentityFile ~/.ssh/id_rsa
          

          请注意上述文件中的空格很重要,如果不正确将导致文件无效。

          USERNAME_HERE 是您的 GitLab 用户名,~/.ssh/id_rsa 是文件系统中 SSH private 密钥的路径。 您已经将其 public 密钥上传到 GitLab。这里是some instructions

          【讨论】:

          • 在全局配置 git 以便可以下载 Go 依赖项时,我总是以错误的方式惹恼我。但这不是同样的问题吗?您正在配置整个系统使用的工具(在这种情况下,如果我正确理解 .netrc,您的机器执行每个 HTTP 请求的方式)只是为了可以下载 Go 依赖项。事实上,这种方式似乎有风险,因为它不会在您发送到该主机的每个请求中都包含该令牌吗?
          • 谢谢,对于 gitlab,以下内容对我有用 echo "machine gitlab.example.com login gitlab-ci-token password ${CI_JOB_TOKEN}" > ~/.netrc && chmod 600 ~/.netrc
          【解决方案6】:

          设置GOPRIVATEgit config ...

          人们在获取私人资源时可能仍然会遇到这样的问题:

          https fetch: Get "https://private/user/repo?go-get=1": EOF
          

          他们不能使用没有.git 扩展的私人仓库。

          原因是 go 工具不知道此 repo 的 VCS 协议,gitsvn 或任何其他协议,与 github.comgolang.org 不同,它们被硬编码到 go 的源代码中。

          然后 go 工具将在获取您的私人仓库之前执行 https 查询:

          https://private/user/repo?go-get=1
          

          如果你的私有仓库不支持https请求,请直接用replace告诉它:

          require private/user/repo v1.0.0
          
          ...
          
          replace private/user/repo => private.server/user/repo.git v1.0.0
          

          https://golang.org/cmd/go/#hdr-Remote_import_paths

          【讨论】:

            【解决方案7】:

            您需要配置一件事。该示例基于 GitHub,但这不应改变流程:

            $ git config --global url.git@github.com:.insteadOf https://github.com/
            $ cat ~/.gitconfig
            [url "git@github.com:"]
                insteadOf = https://github.com/
            $ go get github.com/private/repo
            

            为了让 Go 模块正常工作(使用 Go 1.11 或更高版本),您还需要设置 GOPRIVATE 变量,以避免使用公共服务器来获取代码:

            export GOPRIVATE=github.com/private/repo
            

            【讨论】:

            • 已经做了,其实只需要一个配置,cat 命令只是为了验证。
            • 唯一的缺点是你不能为每个主机设置不同的配置(例如,如果你使用多个提供者)而不改变每次的全局 git 配置。然后最好按照她的描述在«ssh-level»上指定这个:stackoverflow.com/questions/27500861/…
            • go env -w GOPRIVATE=github.com/<OrgNameHere>/*如此处所述stackoverflow.com/questions/58305567/…
            • 是否需要像another answer帖子这样的url引号?
            • 可能有缓存搞砸了。可能是因为尝试在不更改 git 配置的情况下获取一些 repo,如上所述。为我解决了什么问题:rm -rf $GOPATH/pkg/mod/cache/vcs
            【解决方案8】:

            我遇到了.netrc,发现它与此相关。

            创建一个文件~/.netrc,内容如下:

            machine github.com
                login <github username>
                password <github password or Personal access tokens >
            

            完成!

            此外,对于最新的 GO 版本,您可能需要将其添加到环境变量 GOPRIVATE=github.com (我已将其添加到我的.zshrc

            netrc 还使我的开发环境设置更好,因为我的 HTTPS 个人 github 访问现在已配置为跨机器使用(就像我的 SSH 配置一样)。

            生成 GitHub 个人访问令牌:https://github.com/settings/tokens

            请参阅this answer,了解它在 Windows 上与 Git 的具体使用情况

            参考:netrc man page


            如果您想坚持使用 SSH 身份验证,请屏蔽请求以强制使用 ssh

            git config --global url."git@github.com:".insteadOf "https://github.com/"


            更多设置git访问的方法:https://gist.github.com/technoweenie/1072829#gistcomment-2979908

            【讨论】:

            • 这要求您将登录凭据存储在计算机上的纯文本文件中。这不好。
            • 你可能是对的。对我来说,它看起来类似于 AWS 凭证在 ~/.aws 中的存储方式。并且使用 GitHub 的个人访问令牌,我可以根据需求细化访问权限并控制轮换。还有SSH方式?
            【解决方案9】:

            以上所有方法都不适合我。克隆 repo 工作正常,但我仍然收到 unrecognized import 错误。

            因为它代表 Go v1.13,我在文档中发现我们应该像这样使用 GOPRIVATE env 变量:

            $ GOPRIVATE=github.com/ORGANISATION_OR_USER_NAME go get -u github.com/ORGANISATION_OR_USER_NAME/REPO_NAME
            

            【讨论】:

            • 这太简单了……让我开心!
            【解决方案10】:

            对我来说,其他人提供的解决方案在go get期间仍然出现以下错误

            git@gl.nimi24.com:权限被拒绝(公钥)。 致命:无法从远程存储库中读取。 请确保您拥有正确的访问权限 并且存储库存在。

            此解决方案需要什么

            1. 正如其他人所说:

              git config --global url."git@github.com:".insteadOf "https://github.com/"

            2. 从我的 ./ssh/id_rsa 密钥中删除密码,该密钥用于验证与存储库的连接。这可以通过在提示响应时输入空密码来完成:

              ssh-keygen -p

            为什么会这样

            这不是一个很好的解决方法,因为在您的私钥上设置密码总是更好,但它在 OpenSSH 内部的某个地方引起了问题。

            go get 内部使用 git,它使用 openssh 打开连接。 OpenSSH 从.ssh/id_rsa 获取认证所需的证书。从命令行执行 git 命令时,代理可以为您打开 id_rsa 文件,这样您就不必每次都指定密码,但是当在 go get 的腹部执行时,这在我的情况下不起作用案子。 OpenSSH 想要提示您输入密码,但由于它是如何被调用的,所以不可能,它会打印到它的调试日志中:

            read_passphrase: 无法打开 /dev/tty: 没有这样的设备或地址

            然后就失败了。如果您从密钥文件中删除密码,OpenSSH 将在没有提示的情况下获取您的密钥并且它可以工作

            可能是由 Go 并发获取模块并同时打开到 Github 的多个 SSH 连接引起的(如 this article 中所述)。这在一定程度上得到了 OpenSSH 调试日志显示与存储库的初始连接成功的事实的支持,但后来由于某种原因再次尝试,这次选择询问密码。

            但是,上述文章中提出的使用 SSH 连接多路复用的解决方案对我不起作用。作为记录,作者建议将 collowing conf 添加到受影响主机的 ssh 配置文件中:

              ControlMaster auto
              ControlPersist 3600
              ControlPath ~/.ssh/%r@%h:%p
            

            但如前所述,对我来说它不起作用,也许我做错了

            【讨论】:

            • 我认为您可以在不删除 SSH 密钥上的密码短语的情况下使用 ssh-agent,然后再运行 go-get 来预验证您的 ssh-key。
            • 不幸的是,在我的情况下,事先使用代理不起作用
            【解决方案11】:

            看起来像GitLab issue 5769

            在 GitLab 中,由于存储库始终以 .git 结尾,因此我必须在存储库名称的末尾指定 .git 才能使其正常工作,例如:

            import "example.org/myuser/mygorepo.git"
            

            还有:

            $ go get example.org/myuser/mygorepo.git
            

            看起来 GitHub 通过附加 ".git" 解决了这个问题。

            它应该在“Added support for Go's repository retrieval. #5958”中解决,前提是right meta tags are in place
            虽然 Go 本身仍然存在问题:“cmd/go: go get cannot discover meta tag in HTML5 documents”。

            【讨论】:

            • 实际上他们(和其他人)已经支持元标签,但它只适用于公共回购(go get 无需登录即可看到元标签)
            • @secmask 这就是您使用 ssh 的原因:以这种方式提供凭据。
            • 哦,这只是一个选项,我可以使用 http,https 到但go get 命令看起来像go get gitlab.com/secmask/awserver-go.git.git(会要求 http 基本身份验证),看起来也不太好。
            【解决方案12】:

            如果您已经使用 SSH 获得 git,this answer by Ammar Bandukwala 是一个简单的解决方法:


            $ go get 在内部使用 git。下面的一个衬里将通过 SSH 使 git$ go get 克隆你的包。

            Github:

            $ git config --global url."git@github.com:".insteadOf "https://github.com/"
            

            比特桶:

            $ git config --global url."git@bitbucket.org:".insteadOf "https://bitbucket.org/"
            

            【讨论】:

              【解决方案13】:

              生成一个 github oauth 令牌 here 并将您的 github 令牌导出为环境变量:

              export GITHUB_TOKEN=123
              

              设置 git config 使用基本的 auth url:

              git config --global url."https://$GITHUB_TOKEN:x-oauth-basic@github.com/".insteadOf "https://github.com/"
              

              现在你可以go get你的私人仓库了。

              【讨论】:

                【解决方案14】:

                我已经创建了一个用户特定的 ssh-config,所以我的用户会自动使用正确的凭据和密钥登录。

                首先我需要生成一个密钥对

                ssh-keygen -t rsa -b 4096 -C "my@email.here"
                

                并将其保存到例如~/.ssh/id_my_domain。请注意,这也是我连接到我的 Github 帐户的密钥对(私有和公共),所以我的存储在~/.ssh/id_github_com

                然后我创建(或更改)了一个名为 ~/.ssh/config 的文件,其中包含一个条目:

                Host github.com
                    HostName github.com
                    User git
                    IdentityFile ~/.ssh/id_github_com
                

                在另一台服务器上,“ssh-url”是admin@domain.com:username/private-repo.git,该服务器的条目应该是:

                Host domain.com
                    HostName domain.com
                    User admin
                    IdentityFile ~/.ssh/id_domain_com
                

                只是为了澄清您需要确保正确设置UserHostHostName

                现在我可以浏览 go 路径,然后浏览 go get &lt;package&gt;,例如 go get main,其中文件 main/main.go 包含包(来自上面的最后一个示例)domain.com:username/private-repo.git

                【讨论】:

                • 你也可以直接导入一个包:go get hostname.com/username/repo.git(.git扩展名很重要)。
                • 没有扩展名.git 有什么办法吗?为什么会这样?
                • 有趣,原因是我无法获得 repo,没有 .git 扩展名,这是在我的本地 git 配置中,git config --global url."git@gitlab.myserver.com:".insteadOf "https://gitlab.myserver.com/",但子域 gitlab.myserver.com 没有'没有ssl认证,所以我现在使用http而不是https
                【解决方案15】:

                正确的方法是手动将存储库放在正确的位置。一旦存储库在那里,您可以使用go get -u 更新软件包并使用go install 安装它。一个名为

                的包
                github.com/secmask/awserver-go
                

                进入

                $GOPATH/src/github.com/secmask/awserver-go
                

                您输入的命令是:

                cd $GOPATH/src/github.com/secmask
                git clone git@github.com:secmask/awserver-go.git
                

                【讨论】:

                • @secmask go get 被设计为用于常见情况的工具。 Go 团队明确决定不增加可配置性,以便人们遵守标准而不是推出自己的杂物。它从来都不是针对您拥有的情况(即私有存储库)而制作的。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-09-26
                • 1970-01-01
                相关资源
                最近更新 更多