登录
首页 >  Golang >  Go问答

如何在本地服务器上让 go 与存储库协同工作

来源:stackoverflow

时间:2024-03-18 14:36:42 109浏览 收藏

在本地服务器上使用 Git 存储库时,可以利用 Go 的强大功能,通过 go get 命令方便地获取和使用代码包。然而,当存储库位于私有服务器上时,使用 go get 会遇到一些挑战。本文将提供一个全面的指南,介绍如何解决这些挑战,让开发人员能够在私有服务器上有效地使用 Go 与存储库协同工作。

问题内容

我在本地服务器上有一个 git 存储库。我可以使用 git clone [email protected]:/srv/git/liqid.git 进行克隆,其中用户具有 ssh 访问权限并对 git/ 目录进行读/写。

当我尝试将它与 go get -v [email protected]:/srv/git/liqid.git 一起使用时,它给出

go:无法在 GOPATH 模式下使用 path@version 语法

我尝试过各种其他组合,例如省略 :,但它们都失败了。

go get 可以使用本地服务器上的存储库吗?


解决方案


以下是我在 git 存储库位于专用服务器上时对包和模块使用 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.gostringutil.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 上找到

[email protected]:dwschulze/go-package-test-dateutil.git

[email protected]:dwschulze/go-package-test-stringutil.git

[email protected]: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 添加对您的私人 git 服务器的 ssh 密钥访问。

使用 github 上的私有存储库

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

在上面使用 git init 创建的 github/ 下的两个 src/ 目录中创建 git 存储库

package
├── github
│   ├── dateutil
│   │   └── src
│   │       └── ...
│   └── stringutil
│       └── src
|           └── ...

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

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

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

git config --global url."[email protected]:".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.gostringutil.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 存储库,然后添加并提交代码。将遥控器设置为您在私人 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 服务器上使用 git init --bare 创建 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 中第一个元素的 pkg/ 和 src/ 目录中。

└── 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())
}

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

现在您可以使用 go run main.go 来运行代码。

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

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

使用私有存储库创建模块

创建一个与上面创建的 packages/ 目录平行的目录结构。从上面复制 dateutil.gostringutil.go 文件。将包语句分别更改为 datemodstringmod。您稍后将创建 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

在上面的四个 datemodule/stringmodule/ 目录中,使用 git init 创建一个 git 存储库,然后添加并提交文件。

在 github.com 上创建两个名为 go-module-test-dateutilmodgo-module-test-stringutilmod 的私有存储库。按照说明在 github/ 目录下各自的本地 git 存储库中设置遥控器。推送代码。

在您的私人 git 服务器上创建两个 git 存储库

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 存储库中设置遥控器

git remote add origin [email protected]:gitrepo/go-package-test-dateutil


git remote add origin [email protected]: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 public proxy 中提取。

现在运行

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

  go 1.15

现在执行zq​​bczqbmain.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 getgo run main.go 下载模块代码会将代码下载到 $gopath/pkg/mod 中。由于未指定版本,它将提取该模块的最新版本 semantic version tag

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

要指定特定版本,请使用

go get 192.168.0.12/gitrepo/[email protected]

这将更新 go.mod 中的条目(如果已存在)

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

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

  • 修改 ~/.gitconfig
  • 为您的私有服务器上的存储库添加 .git 后缀
  • 您的私有服务器的主机名中必须包含一个点,或使用其 ip 地址
  • 使用 go env -w goprivate=... 设置 goprivate

在不同分支上使用代码

语义版本标记与分支无关,但有一种情况 go get 可以使用分支。如果你想 go 从分支获取最新提交,你可以像这样附加 @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/[email protected]: verifying module: github.com/your-github-username/[email protected]: reading https://sum.golang.org/lookup/github.com/your-github-username/[email protected]: 410 Gone
    server response: not found: github.com/your-github-username/[email protected]: invalid version: unknown revision v0.0.1

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

资源

Using private repos from public git hosting services. A demonstration of how GOPRIVATE and GOPROXY work.

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>