引言:

go get

了解 go get

go get

1. 通过静态方式

1.1 通过仓库域名

go get github.com/example/pkg
github.com

1.2 通过后缀

go get github.com/example/pkg.git
.git

2. 通过动态方式

选择动态方式是因为域名和后缀都无法判断仓库类型,所以一般私有的仓库会使用动态方式。

go get -v git.test.com/example/pkg

2.1 询问仓库

//git.test.com/example/pkg?go-get=1

2.2 分析结果

返回结果如下:

<html>
	<head>
		<meta name="go-import" content="git.test.com/example/pkg git http://git.test.com/example/pkg.git" />
		<meta name="go-source" content="git.test.com/example/pkg http://git.test.com/example/pkg http://git.test.com/example/pkg/-/tree/master{/dir} http://git.test.com/example/pkg/-/blob/master{/dir}/{file}#L{line}" />
	</head>
	<body>go get http://git.test.com/example/pkg</body>
</html>
content
git.test.com/example/pkghttp://git.test.com/example/pkg.git

那么go就知道使用哪个工具拉取包了。

git认证

知道从哪里拉取、怎么拉取,正常就可以拉取go包了,但私有仓库需要git认证。git拉取代码认证的方式有3种:

URI的完整格式:

schema://username:password@host:port?query#fragment

  • schema: 协议,如http/https/ftp等

  • username: 用户名

  • password: 密码

  • host: ip或域名

  • port: 端口

  • query: 查询字符串

  • fragment: 锚点

1. 用户名、密码

需要在拉取时输入用户名密码,但go get时禁止交互(弹框,提示输入用户名密码),我们可以参考URI格式使用 URL中添加用户名密码,即可。但我们go get时也没办法去改这个呀,后面介绍使用 git的 insteadof解决。

http://root:passpwd@git.test.com/example/pkg

2. 用户名、access token(推荐使用)

read_repository

3. ssh

可以在本地创建非对称的加密对(ssh-keygen)。把公钥放到仓库里面去。

git的insteadof

git的insteadof在拉取代码,发送请求前替换请求地址。格式如下:

git config --global url."https://$GIT_USER:$GIT_TOKEN@$GOPRIVATE".insteadOf "https://$GOPRIVATE"
https://$GOPRIVATEhttps://$GIT_USER:$GIT_TOKEN@$GOPRIVATE

注:必须设置成 --global 与 --system,git 支持 --global、--local、--system。

  • --system 作用范围太大了,此机器的其他用户或项目都使用了此设置。

  • --local只能针对当前项目(所以必须在项目所在目录,它会找.git目录中的设置),go使用git命令时目录可能存在问题。【未验证】

例如:

git config --global url."https://root:VUQsGPQdxy5CDQ9xEs24@git.test.com".insteadOf "http://git.test.com"
http://git.test.comhttps://root:VUQsGPQdxy5CDQ9xEs24@git.test.comrootVUQsGPQdxy5CDQ9xEs24
/http://git.test.com/:https://root:VUQsGPQdxy5CDQ9xEs24@git.test.com:

例如:

go get http://git.test.com/example/pkg
go get git.test.com/example/pkggo get http://git.test.com/example/pkg
http://git.test.comhttps://root:VUQsGPQdxy5CDQ9xEs24@git.test.com
https://root:VUQsGPQdxy5CDQ9xEs24@git.test.com/example/pkg
git clone https://root:VUQsGPQdxy5CDQ9xEs24@git.test.com/example/pkg

完整流程

go env -w GOPRIVATE=git.test.com
set GONOPROXY=git.test.com  # 拉取git.test.com时不使用GOPROXY代理服务器
set GONOSUMDB=git.test.com  # 拉取包成功后不进行签名校验,因为我们的私有库没有生成签名
git config --global url."https://root:VUQsGPQdxy5CDQ9xEs24@git.test.com".insteadOf "http://git.test.com"
...省略不相关的配置
[url "https://root:VUQsGPQdxy5CDQ9xEs24@git.test.com"]
	insteadOf = http://git.test.com
go get git.test.com/example/pkg

其他

1. 有时候配置了 git config 的insteadOf 后还是不好使,可能是因为之前设置过,需要把之前的删除。

先查看所有设置

> git config --global -l

# 结果显示

...省略不相关的配置
url.https://root:VUQsGPQdxy5CDQ9xEs24@git.test.com.insteadof=http://git.test.com
...省略不相关的配置

再进行删除(复制=号之前的所有字符串)

git config --global --unset url.https://root:VUQsGPQdxy5CDQ9xEs24@git.test.com.insteadof

2. 凭证管理

C:\Program Files\Git\mingw64\libexec\git-core
git-credential-cache.exe
git-credential-cache--daemon.exe
git-credential-manager-core.exe
git-credential-store.exe
git-credential-wincred.exe

查看git使用的凭证管理工具:

> git config --list

...省略不相关的配置
credential.helper=manager-core
credential.helper=store 
...省略不相关的配置

Git 甚至允许你配置多个辅助工具。 当查找特定服务器的凭证时,Git 会按顺序查询,并且在找到第一个回答时停止查询。 当保存凭证时,Git 会将用户名和密码发送给 所有 配置列表中的辅助工具,它们会按自己的方式处理用户名和密码。

manager-corestoreC:\Program Files\Git\mingw64\libexec\git-coregit-credential-manager-core.exegit-credential-store.exefoogit config --global credential.helper foogit-credential-foo.exe
git-credential-manager-core.exe控制面板\用户帐户\凭证管理\管理windows凭证

3. go mod cache

go get 拉取代码时后在$GOPATH/pkg/下生成缓存,而且会有2级缓存。

第1级缓存:首先会在$GOPATH/pkg/mod/cache目录中下载所需要的包,以压缩所格式保存。

第2级缓存:在$GOPATH/pkg/mod中解压cache中的包,放在与cache目录同级。

这样我们 go get 时会先检查第2级缓存,如果不存在,再去检查第1级缓存,如果都不存在再连网去仓库拉取包,并生成缓存。

可以手动删除缓存或通过命令(命令会将整个$GOPATH/pkg/mod目录删除):

go clean -modcache

所以有时在认证后拉取的包缓存在了本地,即使认证的access token或密码修改了,再go get或go mod tidy时也可以成功使用包,也可能是使用了之前的缓存。

参考文章

更新精彩文章请关注微信公众号:大胡几哥哥