go - 如何在本地服务器上使用 repo
问题描述
我在本地服务器上有一个 git repo。我可以从它克隆git clone user@10.xxx.yyy.zzz:/srv/git/liqid.git
用户具有 ssh 访问权限并读/写到 git/ 目录的位置。
当我尝试使用它go get -v user@10.xxx.yyy.zzz:/srv/git/liqid.git
时
go: cannot use path@version syntax in GOPATH mode
我尝试了各种其他组合,例如省略:
,但它们都失败了。
可以go get
在本地服务器上使用 repo 吗?
解决方案
当 git repo 在私有服务器上时,这是我学到的关于使用go get
包和模块的知识。我希望它可以帮助其他人将所有步骤记录在一个地方。
在私有服务器上使用带有 git 存储库的包和模块
以下是在私有服务器上使用带有 git 存储库的 Go 包和模块所需的所有步骤。这些是 IP 地址为 10.xxx.yyy.zzz 或 192.168.xxx.yyy 的服务器。假设这些服务器上不存在 github 或 gitlab,因此端口 80 上没有运行 Web 服务器,这是go get
基于的假设。您的私人服务器只需要sshd
运行。
安装最新版本的 Go 并确保设置了 GOPATH。GOPATH 中的第一个元素是将这些示例中的代码下载到的位置。
您将需要网络上的另一台计算机来创建 git 存储库。这将是您的私人 git 服务器。
如果您想跳过所有设置步骤和示例代码,您可以查看两个主要差异部分,其中列出了将包或模块与私有服务器而不是公共 git 存储库一起使用时的差异。
源代码
将dateutil.go
和stringutil.go
放在下面显示的包和模块的目录结构中。
dateutil.go:
package datepackage
import "time"
func GetTime() time.Time {
return time.Now().Local()
}
stringutil.go:
package stringpackage
import "strings"
func ToUpperCase(s string) string {
return strings.ToUpper(s)
}
main.go(将 main.go 放在如下所示的目录结构之外):
package main
import (
"fmt"
"github.com/your-github-username/go-package-test-dateutil/datepackage"
"github.com/your-github-username/go-package-test-stringutil/stringpackage"
)
func main() {
fmt.Println("github: " + stringpackage.ToUpperCase("test"))
fmt.Println("github: " + datepackage.GetTime().String())
}
这些文件可以在 github.com 上找到
git@github.com:dwschulze/go-package-test-dateutil.git
git@github.com:dwschulze/go-package-test-stringutil.git
git@github.com:dwschulze/go-module-package-test-drivers.git
使用 GOPATH 约定创建包
在 GOPATH 之外创建一个像这样的目录结构并添加上面的文件。这遵循 GOPATH 约定,但您的 GOPATH 中不需要这些文件。
package
├── github
│ ├── dateutil
│ │ └── src
│ │ └── datepackage
│ │ └── dateutil.go
│ └── stringutil
│ └── src
│ └── stringpackage
│ └── stringutil.go
└── your-local-git-repo-hostname
├── dateutil
│ └── src
│ └── datepackage
│ └── dateutil.go
└── stringutil
└── src
└── stringpackage
└── stringutil.go
your-local-git-repo-hostname
是您将在其中创建 git 存储库的私有 git 服务器的主机名或 IP 地址(不是您当前拥有此代码的机器)。有一个未记录的要求,即go get
命令的主机名中包含一个.
。如果你的私有 git 服务器的主机名没有.
,那么使用它的 IP 地址。使用ssh-copy-id
.
在 github 上使用私有仓库
我们将从最简单的情况开始,使用来自 github.com 的包。您需要一个带有 ssh 密钥访问设置的 github 帐户。
在上面创建的两个src/
目录中创建 git reposgithub/
git init
package
├── github
│ ├── dateutil
│ │ └── src
│ │ └── ...
│ └── stringutil
│ └── src
| └── ...
datepackage/
将和目录分别添加并提交stringpackage/
到您的 git 存储库。
在您的 github.com 帐户中创建两个名为go-package-test-dateutil
和的私有 github存储库。go-package-test-stringutil
按照说明将src/
目录中本地 git 存储库中的遥控器设置为各自的 github 存储库。推送代码。
由于您的存储库是私有的,您必须使用 ssh 公钥访问来下载代码。由于go get
默认使用 https,因此您需要将其添加到您的~/.gitconfig
文件中:
git config --global url."git@github.com:".insteadOf "https://github.com/"
运行这些命令,将您刚刚推送到 github.com 的代码放入您的GOPATH
:
go get github.com/your-github-username/go-package-test-stringutil/stringpackage/
go get github.com/your-github-username/go-package-test-dateutil/datepackage/
包被下载到GOPATH 中第一个元素的pkg/
和目录中。src/
在您在上面创建的文件所在的目录中main.go
键入go run main.go
,结果将打印到控制台。
在您的私有服务器上创建 Git 存储库
现在您将在您的私有 git 服务器上创建 git 存储库。为了保持简单,您只需使用git init --bare
. 无需安装 github 或 gitlab。在您的私人 git 服务器上,您需要sshd
从您的代码所在的机器运行并拥有 ssh 密钥访问权限。新的回购将在/home/myusername/gitrepo
.
git init /home/myusername/gitrepo/go-package-test-dateutil --bare
git init /home/myusername/gitrepo/go-package-test-stringutil --bare
该go get
命令有一个未记录的要求,即主机名中包含一个.
。如果你的私有 git 服务器的主机名没有.
,那么使用它的 IP 地址,这就是我将在本示例的其余部分执行的操作。假设机器的IP地址是192.168.0.12
将您之前创建的dateutil.go
和stringutil.go
文件复制到以下目录中your-local-git-repo-hostname
:
package
├── github
| ...
└── your-local-git-repo-hostname
├── dateutil
│ └── src
│ └── datepackage
│ └── dateutil.go
└── stringutil
└── src
└── stringpackage
└── stringutil.go
在这两个src/
目录中像以前一样创建本地 git repos 并添加并提交代码。将远程设置为您在私有 git 服务器上创建的 git 存储库
git remote add origin myusername@your-local-git-repo-hostname:gitrepo/go-package-test-dateutil
git remote add origin myusername@your-local-git-repo-hostname:gitrepo/go-package-test-stringutil
您需要~/.gitconfig
为您的私人 git 服务器输入另一个条目:
git config --global url."myusername@your-local-git-repo-hostname:".insteadOf "https://192.168.0.12/"
现在推送代码。请注意,此代码尚未在您的 GOPATH 中。
用于go get
从您的私有 git 服务器检索代码。有必要git init --bare
在您的私有 git 服务器上创建 git 存储库的目录名称中添加“.git”后缀。这go get
表明这是一个 git 存储库,而不是其他一些版本控制系统。
go get 192.168.0.12/gitrepo/go-package-test-stringutil.git/stringpackage
go get 192.168.0.12/gitrepo/go-package-test-dateutil.git/datepackage
包被下载到你的GOPATH
.
└── src
├── 192.168.0.12
│ └── gitrepo
│ ├── go-module-test-dateutil.git
│ │ ├── dateutil.go
│ │ └── go.mod
│ ├── go-package-test-dateutil.git
│ │ └── datepackage
│ │ └── dateutil.go
│ └── go-package-test-stringutil.git
│ └── stringpackage
│ └── stringutil.go
在您的main.go
代码中,将两个导入语句添加到您的私有 git 服务器上的包中
package main
import (
dpkg "192.168.0.12/gitrepo/go-package-test-dateutil.git/datepackage"
strpkg "192.168.0.12/gitrepo/go-package-test-stringutil.git/stringpackage"
"fmt"
"github.com/your-github-username/go-package-test-dateutil/datepackage"
"github.com/your-github-username/go-package-test-stringutil/stringpackage"
)
func main() {
fmt.Println("github: " + stringpackage.ToUpperCase("test"))
fmt.Println("github: " + datepackage.GetTime().String())
fmt.Println("local: " + strpkg.ToUpperCase("test"))
fmt.Println("local: " + dpkg.GetTime().String())
}
请注意在两个新语句中使用别名dpkg
和,因为这些语句具有重复的包名称(导入语句中的最后一个元素)。strpkg
import
import
现在您可以使用go run main.go
.
在guthub.com 上使用私有repo 和在私有git 服务器上使用repo 的主要区别:
- 修改 ~/.gitconfig
- 在 go get 语句中添加 .git 后缀
go get
和 语句中的主机名import
必须有一个点
使用私有存储库创建模块
创建一个与您在上面创建的目录平行的目录结构packages/
。从上面复制dateutil.go
和stringutil.go
文件。将包语句分别更改为datemod
和stringmod
。稍后您将创建这些go.mod
文件。
module
├── github
│ ├── datemodule
│ │ ├── dateutil.go
│ │ └── go.mod
│ └── stringmodule
│ ├── go.mod
│ └── stringutil.go
└── 192.168.0.12
├── datemodule
│ ├── dateutil.go
│ └── go.mod
└── stringmodule
├── go.mod
└── stringutil.go
请注意,目录名称与包名称不同。包不必遵循目录名称。
go.mod
通过在这些目录中执行以下命令来生成文件:
在github/datemodule/
go mod init github.com/your-github-username/go-module-test-dateutilmod
在github/stringmodule/
go mod init github.com/your-github-username/go-module-test-stringutilmod
在192.168.0.12/datemodule/
go mod init 192.168.0.12/gitrepo/go-module-test-dateutil.git
在192.168.0.12/stringmodule/
go mod init 192.168.0.12/gitrepo/go-module-test-stringutil.git
在上面的四个目录中创建一个 git repodatemodule/
并添加和提交文件。stringmodule/
git init
在 github.com 上创建两个名为go-module-test-dateutilmod
和的私有存储库go-module-test-stringutilmod
。按照说明在github/
目录下的各自本地 git 存储库中设置遥控器。推送代码。
在您的私人 git 服务器上创建两个 git repos
git init /home/myusername/gitrepo/go-module-test-dateutil --bare
git init /home/myusername/gitrepo/go-module-test-stringutil --bare
192.168.0.12/
在目录下的相应 git repos 中设置遥控器
git remote add origin myusername@192.168.0.12:gitrepo/go-package-test-dateutil
git remote add origin myusername@192.168.0.12:gitrepo/go-package-test-stringutil
推送代码。
现在您有四个不同的模块,两个分别位于您的 github.com 帐户和您的私有 git 服务器的存储库中。
在另一个目录中创建一个main.go
程序来使用这些模块:
package main
import (
datemodlocal "192.168.0.12/gitrepo/go-module-test-dateutil.git"
stringmodlocal "192.168.0.12/gitrepo/go-module-test-stringutil.git"
"fmt"
"github.com/your-github-username/go-module-test-dateutilmod"
"github.com/your-github-username/go-module-test-stringutilmod"
)
func main() {
fmt.Println("github: " + stringmod.ToUpperCase("test"))
fmt.Println("github: " + datemod.GetTime().String())
fmt.Println("local: " + stringmodlocal.ToUpperCase("test"))
fmt.Println("local: " + datemodlocal.GetTime().String())
fmt.Println("local toString: " + datemodlocal.GetTimeStr())
}
要使用带有私有仓库的模块,我们必须设置GOPRIVATE
go env -w GOPRIVATE=192.168.0.12/gitrepo/*,github.com/your-github-username/*
何时GOPRIVATE
设置模块将直接从指定的 git 存储库而不是Go 公共代理中提取。
现在运行
$ go mod init module-driver
go: creating new go.mod: module module-driver
$ cat go.mod
module module-driver
go 1.15
现在执行main.go
. 在运行代码之前,它将从 github.com 和您的私有 git 服务器下载模块:
$ go run main.go
go: finding module for package github.com/dwschulze/go-module-test-dateutilmod
go: finding module for package github.com/dwschulze/go-module-test-stringutilmod
go: finding module for package 192.168.0.12/gitrepo/go-module-test-stringutil.git
go: finding module for package 192.168.0.12/gitrepo/go-module-test-dateutil.git
go: downloading 192.168.0.12/gitrepo/go-module-test-stringutil.git v0.0.1
go: downloading 192.168.0.12/gitrepo/go-module-test-dateutil.git v0.0.3
go: downloading github.com/dwschulze/go-module-test-dateutilmod v0.0.1
go: downloading github.com/dwschulze/go-module-test-stringutilmod v0.0.1
go: found 192.168.0.12/gitrepo/go-module-test-dateutil.git in 192.168.0.12/gitrepo/go-module-test-dateutil.git v0.0.3
go: found 192.168.0.12/gitrepo/go-module-test-stringutil.git in 192.168.0.12/gitrepo/go-module-test-stringutil.git v0.0.1
go: found github.com/dwschulze/go-module-test-dateutilmod in github.com/dwschulze/go-module-test-dateutilmod v0.0.1
go: found github.com/dwschulze/go-module-test-stringutilmod in github.com/dwschulze/go-module-test-stringutilmod v0.0.1
github: TEST
github: 2020-12-08 07:57:02.969147007 -0700 MST
local: TEST
local: 2020-12-08 07:57:02.969220121 -0700 MST
local toString: 2020-12-08 07:57:02.969222359 -0700 MST (dev2 branch)
local GetTimeStr3: 2020-12-08 07:57:02.96925053 -0700 MST (dev2 branch)
在运行代码之前,您不必运行go get
来下载这些模块。也被go.mod
修改了
$ cat go.mod
module module-driver
go 1.15
require (
192.168.0.12/gitrepo/go-module-test-dateutil.git v0.0.3 // indirect
192.168.0.12/gitrepo/go-module-test-stringutil.git v0.0.1 // indirect
github.com/dwschulze/go-module-test-dateutilmod v0.0.1 // indirect
github.com/dwschulze/go-module-test-stringutilmod v0.0.1 // indirect
)
您可以使用 go get 下载模块以测试您的环境是否设置正确:
go get 192.168.0.12/gitrepo/go-module-test-dateutil.git
go get 192.168.0.12/gitrepo/go-module-test-stringutil.git
go get github.com/your-github-username/go-module-test-dateutilmod
go get github.com/your-github-username/go-module-test-stringutilmod
再次注意在.git
您的私有 git 服务器的存储库路径上使用后缀。没有这个go get
将使用 https 而不是 git(它将使用 ssh)。
运行go get
修改go.mod
文件。虽然有些人说您可以手动修改go.mod
文件,但其他人说您不应该go.mod
手动编辑,而是使用go get
来进行任何修改。
下载模块代码或者go get
将go run main.go
代码下载到$GOPATH/pkg/mod
. 由于没有指定版本,它将为该模块提取最新的语义版本标签。
语义版本控制是使用只是提交的标签完成的。标签独立于分支,因此如果最新semver
版本是在 master 以外的分支上完成的,它将拉取该版本。
要指定特定版本,请使用
go get 192.168.0.12/gitrepo/go-module-test-dateutil.git@v0.0.1
go.mod
如果条目已经存在,这将更新条目
您应该能够删除$GOPATH/pkg/mod/
目录并go run main.go
再次执行。在运行代码之前,您会看到 Go 下载了所需的模块。
使用私有存储库中的模块时的主要区别
- 修改 ~/.gitconfig
- 为您的私有服务器上的存储库添加 .git 后缀
- 您的私有服务器的主机名中必须有一个点,或者使用它的 IP 地址
- 设置
GOPRIVATE
为go env -w GOPRIVATE=...
在不同的分支上使用代码
语义版本标签独立于分支,但有一种情况go get
可以使用分支。如果你想go get
从一个分支获得最新的提交,你可以@branchname
像这样追加:
go get 192.168.0.12/gitrepo/go-module-test-dateutil.git@branchname
如果分支上的最新提交没有semver
标签,将使用下一个标签号和时间戳和哈希go get
创建伪版本。semver
常见问题
410 Gone
下载模块时出现错误是什么意思?
go get github.com/your-github-username/go-module-test-dateutilmod
go: downloading github.com/your-github-username/go-module-test-dateutilmod v0.0.1
go get github.com/your-github-username/go-module-test-dateutilmod: github.com/your-github-username/go-module-test-dateutilmod@v0.0.1: verifying module: github.com/your-github-username/go-module-test-dateutilmod@v0.0.1: reading https://sum.golang.org/lookup/github.com/your-github-username/go-module-test-dateutilmod@v0.0.1: 410 Gone
server response: not found: github.com/your-github-username/go-module-test-dateutilmod@v0.0.1: invalid version: unknown revision v0.0.1
如果您没有设置 GOPRIVATE,就会发生这种情况。Go 尝试从 Go 公共代理中检索您的(私有)模块,但在那里找不到它们。
资源
推荐阅读
- vb.net - 如何一次填充多个组合框?
- javascript - 根据星期几更改 div 的颜色。Javascript
- excel - 如何在 Excel 32 位和 64 位中运行此 VBA 代码
- sql - SQL 按查询分区
- arduino - 剪掉Arduino串口监视器中显示的部分数据
- karate - 空手道加特林名称解析器
- php - 从另一个文件到 page.php 的 PHP 链接
- javascript - 将对象转换为数组
- python - Celery/Redis 无限加载
- ios - “UNLocationNotificationTrigger”在 Mac Catalyst 中不可用