“去获取”私有存储库的正确方法是啥?

Posted

技术标签:

【中文标题】“去获取”私有存储库的正确方法是啥?【英文标题】:What's the proper way to "go get" a private repository?“去获取”私有存储库的正确方法是什么? 【发布时间】:2015-02-14 12:59:59 【问题描述】:

经过多次谷歌尝试后,我正在寻找让$ 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 不太好,还有其他方法吗?

【问题讨论】:

【参考方案1】:

您需要配置一件事。该示例基于 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»上指定这个:***.com/questions/27500861/… go env -w GOPRIVATE=github.com/<OrgNameHere>/*如此处所述***.com/questions/58305567/… 是否需要像another answer帖子这样的url引号? 可能有缓存搞砸了。可能是因为尝试在不更改 git 配置的情况下获取一些 repo,如上所述。为我解决了什么问题:rm -rf $GOPATH/pkg/mod/cache/vcs【参考方案2】:

正确的方法是手动将存储库放在正确的位置。一旦存储库在那里,您可以使用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 团队明确决定不增加可配置性,以便人们遵守标准而不是推出自己的杂物。它从来都不是针对您拥有的情况(即私有存储库)而制作的。【参考方案3】:

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

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

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

     $ git config --global http.extraheader "PRIVATE-TOKEN: YOUR_PRIVATE_TOKEN"
    

    配置您的 git 以将请求从 http 转换为 ssh

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

    终于可以正常使用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 [...]【参考方案4】:

对于使用私有 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【参考方案5】:

以上所有方法都不适合我。克隆 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

【讨论】:

这太简单了……让我开心!【参考方案6】:

如果您已经使用 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/"

【讨论】:

【参考方案7】:

生成一个 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你的私人仓库了。

【讨论】:

【参考方案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】:

看起来像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 基本身份验证),看起来也不太好。【参考方案10】:

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

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

【讨论】:

【参考方案11】:

我创建了一个特定于用户的 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 【参考方案12】:

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

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

此解决方案需要什么

    正如其他人所说:

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

    从我的 ./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。 不幸的是,在我的情况下,事先使用代理不起作用【参考方案13】:

设置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

【讨论】:

【参考方案14】:

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

之前我执行了gitconfig,其令牌已过期,下次使用新令牌执行命令时请确保删除之前的令牌。

【讨论】:

【参考方案15】:

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

module go.yourcompany.tld/the_repo

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

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

编辑

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

【讨论】:

以上是关于“去获取”私有存储库的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有密码的 SSH 密钥身份验证“去获取”私有存储库

使用仅标头库的正确方法是啥?

vue组件库的正确使用方法是啥?

使用 PyPi 通过 git clone 传递令牌的正确方法是啥?

在没有第三方库的情况下从 JSON 获取动态对象的最佳方法是啥?

私有 Github 存储库的私有页面