“去获取”私有存储库的正确方法是啥?
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
【讨论】:
@secmaskgo 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
只是为了澄清您需要确保User
、Host
和HostName
设置正确。
现在我可以浏览 go 路径,然后浏览 go get <package>
,例如 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】:设置GOPRIVATE
和git config ...
后
人们在获取私人资源时可能仍然会遇到这样的问题:
https fetch: Get "https://private/user/repo?go-get=1": EOF
如果没有.git
扩展,他们不能使用私人回购。
原因是 go 工具不知道此 repo 的 VCS 协议,git
或 svn
或任何其他协议,与 github.com
或 golang.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 密钥身份验证“去获取”私有存储库
使用 PyPi 通过 git clone 传递令牌的正确方法是啥?