如何使用本地服务器上的 repo 开始工作

Dea*_*lze 1 github go

我在本地服务器上有一个 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 吗?

Dea*_*lze 6

以下是go get当 git 存储库位于私人服务器上时,我了解到的有关用于包和模块的知识。我希望它可以帮助其他人将所有步骤记录在一个地方。

在私有服务器上使用带有 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.gostringutil.go放在下面显示的包和模块的目录结构中。

dateutil.go:

package datepackage

import "time"

func GetTime() time.Time {
    return time.Now().Local()
}
Run Code Online (Sandbox Code Playgroud)

stringutil.go:

package stringpackage

import "strings"

func ToUpperCase(s string) string {

    return strings.ToUpper(s)
}
Run Code Online (Sandbox Code Playgroud)

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())
}
Run Code Online (Sandbox Code Playgroud)

这些文件可以在 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
Run Code Online (Sandbox Code Playgroud)

使用 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
Run Code Online (Sandbox Code Playgroud)

your-local-git-repo-hostname是您的私有 git 服务器的主机名或 IP 地址,您将在其中创建 git repos(而不是您当前拥有此代码的机器)。go get命令的主机名中有一个未记录的要求.。如果您的私有 git 服务器的主机名中没有.,则使用其 IP 地址。将 ssh 密钥访问权限添加到您的私有 git 服务器ssh-copy-id

在 github 上使用私有仓库

我们将从最简单的情况开始,使用来自 github.com 的包。您需要一个具有 ssh 密钥访问设置的 github 帐户。

在上面创建的两个src/目录中创建 git reposgithub/使用git init

package
??? github
?   ??? dateutil
?   ?   ??? src
?   ?       ??? ...
?   ??? stringutil
?       ??? src
|           ??? ...
Run Code Online (Sandbox Code Playgroud)

分别将datepackage/stringpackage/目录添加并提交到您的 git 存储库。

在您在 github.com 上的帐户中创建两个名为go-package-test-dateutil和 的私有 githubgo-package-test-stringutil存储库。按照说明将src/目录中本地 git存储库中的遥控器设置为它们各自的 github 存储库。推代码。

由于您的存储库是私有的,您必须使用 ssh 公钥访问来下载代码。由于go get默认使用 https,因此您需要将其添加到您的~/.gitconfig文件中:

git config --global url."git@github.com:".insteadOf "https://github.com/"
Run Code Online (Sandbox Code Playgroud)

运行这些命令将您刚刚推送到 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/
Run Code Online (Sandbox Code Playgroud)

这些包被下载到GOPATH 中第一个元素的pkg/src/目录中。

main.go上面创建的文件所在的目录中键入go run main.go,结果将打印到控制台。

在您的私人服务器上创建 Git 存储库

现在,您将在您的私有 git 服务器上创建 git repos。为了保持简单,您只需使用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
Run Code Online (Sandbox Code Playgroud)

go get命令有一个未记录的要求,即主机名中有一个.。如果您的私有 git 服务器的主机名中没有 a .,则使用其 IP 地址,这就是我将在本示例的其余部分中执行的操作。假设机器的IP地址是192.168.0.12

将您之前创建的dateutil.gostringutil.go文件复制到以下目录中your-local-git-repo-hostname

package
??? github
|   ...
??? your-local-git-repo-hostname
    ??? dateutil
    ?   ??? src
    ?       ??? datepackage
    ?           ??? dateutil.go
    ??? stringutil
        ??? src
            ??? stringpackage
                ??? stringutil.go
Run Code Online (Sandbox Code Playgroud)

在这两个src/目录中,像之前一样创建本地 git repos,然后添加和提交代码。将远程设置为您在私有 git 服务器上创建的 git repo

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
Run Code Online (Sandbox Code Playgroud)

~/.gitconfig的私有 git 服务器需要另一个条目:

git config --global url."myusername@your-local-git-repo-hostname:".insteadOf "https://192.168.0.12/"
Run Code Online (Sandbox Code Playgroud)

现在推送代码。请注意,此代码尚未在您的 GOPATH 中。

用于go get从您的私有 git 服务器检索代码。有必要将“.git”后缀添加到您在git init --bare私有 git 服务器上创建 git repos 的目录名称。这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
Run Code Online (Sandbox Code Playgroud)

包被下载到你的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
Run Code Online (Sandbox Code Playgroud)

在您的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())
}
Run Code Online (Sandbox Code Playgroud)

请注意别名dpkgstrpkg在两个新import语句中的使用,因为这些import语句具有重复的包名称(import 语句中的最后一个元素)。

现在您可以使用go run main.go.

在guthub.com 上使用私有repo 和在私有git 服务器上使用repo 之间的主要区别:

  • 修改 ~/.gitconfig
  • 在 go get 语句中添加 .git 后缀
  • go getimport语句中的主机名必须有一个点

使用私有存储库创建模块

创建一个与packages/上面创建的目录平行的目录结构。从上面复制dateutil.gostringutil.go文件。将包语句分别更改为datemodstringmodgo.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
Run Code Online (Sandbox Code Playgroud)

请注意,目录名称与包名称不同。包不必遵循目录名称。

go.mod通过在这些目录中执行以下命令来生成文件:

github/datemodule/

go mod init github.com/your-github-username/go-module-test-dateutilmod
Run Code Online (Sandbox Code Playgroud)

github/stringmodule/

go mod init github.com/your-github-username/go-module-test-stringutilmod
Run Code Online (Sandbox Code Playgroud)

192.168.0.12/datemodule/

go mod init 192.168.0.12/gitrepo/go-module-test-dateutil.git
Run Code Online (Sandbox Code Playgroud)

192.168.0.12/stringmodule/

go mod init 192.168.0.12/gitrepo/go-module-test-stringutil.git
Run Code Online (Sandbox Code Playgroud)

在上面的四个datemodule/stringmodule/目录中创建一个 git repogit 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

推代码。

现在您有四个不同的模块,每个模块在您的 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())
}
Run Code Online (Sandbox Code Playgroud)

要使用带有私有存储库的模块,我们必须设置 GOPRIVATE

go env -w GOPRIVATE=192.168.0.12/gitrepo/*,github.com/your-github-username/*
Run Code Online (Sandbox Code Playgroud)

When GOPRIVATEis set 模块将直接从指定的 git repos 而不是Go public proxy 中拉取

现在运行

$ go mod init module-driver
  go: creating new go.mod: module module-driver
$ cat go.mod
  module module-driver

  go 1.15
Run Code Online (Sandbox Code Playgroud)

现在执行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)
Run Code Online (Sandbox Code Playgroud)

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
)
Run Code Online (Sandbox Code Playgroud)

您可以使用 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
Run Code Online (Sandbox Code Playgroud)

再次注意在.git您的私有 git 服务器的存储库路径上使用后缀。没有这go get将使用 https 而不是 git (它将使用 ssh)。

运行go get修改go.mod文件。虽然有些人说您可以手动修改go.mod文件,但其他人说您不应go.mod手动编辑,而应使用go get进行任何修改。

使用go getgo run main.go将代码下载到$GOPATH/pkg/mod. 由于未指定版本,它将为该模块提取最新的语义版本标签

语义版本控制是通过标签完成的,这些标签只是一个提交。标签独立于分支,因此如果最新版本semver是在 master 以外的分支上完成的,它将拉取该版本。

指定特定版本使用

go get 192.168.0.12/gitrepo/go-module-test-dateutil.git@v0.0.1
Run Code Online (Sandbox Code Playgroud)

go.mod如果条目已经存在,这将更新条目

您应该能够删除$GOPATH/pkg/mod/目录并go run main.go再次执行。在运行代码之前,您将看到 Go 下载所需的模块。

使用私有存储库中的模块时的主要区别

  • 修改 ~/.gitconfig
  • 在您的私有服务器上为 repos 添加 .git 后缀
  • 您的私有服务器的主机名中必须有一个点,或者使用它的 IP 地址
  • 设置GOPRIVATEgo env -w GOPRIVATE=...

在不同的分支上使用代码

语义版本标签独立于分支,但有一种情况go get可以使用分支。如果你想go get从一个分支进行最新的提交,你可以@branchname像这样附加:

go get 192.168.0.12/gitrepo/go-module-test-dateutil.git@branchname
Run Code Online (Sandbox Code Playgroud)

如果分支上的最新提交没有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
Run Code Online (Sandbox Code Playgroud)

如果您没有设置 GOPRIVATE,就会发生这种情况。Go 尝试从 Go 公共代理检索您的(私有)模块,但在那里找不到它们。

资源

使用来自公共 git 托管服务的私有存储库。GOPRIVATE 和 GOPROXY 如何工作的演示。