关于git:Go,go get,go install,本地包和版本控制

Go, go get, go install, local packages, and version control

我无法理解创建具有本地包的go项目的工作流。

假设我创建了一个新项目,使用git进行版本控制,它有一个main.go文件和一个tools.go文件,该文件将在package utils中。所以我有这样的目录结构:

1
2
3
4
/myproject/
   main.go
   utils/
     tools.go

main.go如下:

1
2
3
4
5
package main
import"./utils"
func main() {
    utils.DoSomthing()
}

和tools.go如下所示:

1
2
3
package utils;
func DoSomething() {
}

一切都在本地正常工作,使用go build和go run。但是这是在Github上托管的,我希望能够让其他人使用go get命令来安装它。因此,本地包导入必须更改为使用格式"github.com/user/project/utils",这是有效的,除非现在我有两个源代码副本,真正的问题是具有git历史记录的副本有一个使用下载副本的导入。因此,如果我正在使用git历史记录进行复制,对tools.go所做的任何更改都将被忽略,因为它将使用下载的副本。

所以我想知道是否有人可以解释在同一个项目中使用Go-Get、版本控制和包导入的正确方法。


我刚刚就如何使用新的go工具和github.com编写了一个简短的分步指南。你可能会发现它很有用:

1。设置GoPath

您可以将环境变量GOPATH设置为您喜欢的任何目录。如果您有更大的项目,那么为每个项目创建不同的GoPath可能是一个好主意。我将特别推荐这种方法用于部署,以便为项目A更新库不会破坏项目B,这可能需要非常相同的库的早期版本。

还要注意,您可以将gopath设置为目录列表,由冒号分隔。因此,您可能有一个包含所有常用包的gopath,并为每个项目使用附加包或现有包的不同版本分离gopath。

但是,除非您同时在许多不同的go项目上工作,否则可能只在本地有一个gopath就足够了。那么,让我们创建一个:

1
mkdir $HOME/gopath

然后,您需要设置两个环境变量来告诉Go工具它可以在哪里找到现有的Go包以及应该在哪里安装新的Go包。最好将以下两行添加到您的~/.bashrc~/.profile中(之后不要忘记重新加载.bashrc)。

1
2
export GOPATH="$HOME/gopath"
export PATH="$GOPATH/bin:$PATH"

2。创建新项目

如果您想创建一个新的go项目,该项目应该稍后在github.com上托管,那么您应该在$GOPATH/src/github.com/myname/myproject下创建这个项目。路径与github.com repo的URL匹配是很重要的,因为go工具将遵循相同的约定。因此,让我们在这里创建项目根目录并初始化一个新的Git存储库:

1
2
3
mkdir -p $GOPATH/src/github.com/myname/myproject
cd $GOPATH/src/github.com/myname/myproject
git init

因为我不喜欢键入这么长的路径,所以我通常会在主文件夹中为当前正在处理的项目创建符号链接:

1
ln -s $GOPATH/src/github.com/myname/myproject ~/myproject

三。编写应用程序

开始编码,不要忘记使用git addgit commit文件。此外,不要将相对进口产品(如import"./utils")用于子包。它们目前没有文档,根本不应该使用,因为它们不能与Go工具一起工作。使用像github.com/myname/myproject/utils这样的进口产品。

4。发布项目

在github.com上创建一个新的存储库,如果以前没有这样做,请上载ssh公钥,然后将更改推送到远程存储库:

1
2
git remote add origin [email protected]:myname/myproject.git
git push origin master

5。继续处理您的项目

如果在.bashrc中设置了gopath,并且在主文件夹中创建了指向项目的符号链接,则只需键入cd myproject/并在其中编辑一些文件即可。然后,您可以使用git commit -a提交更改,并通过执行git push将更改发送到github.com。


您可能不需要源文件的两份副本。遵循如何编写Go代码,您应该有一条执行Go开发的路径,比如说"godev",在该路径下是"src"目录,在该目录下是"github.com/user/project"和"github.com/user/project/utils"。(我同意,这似乎有点僵化,但向我们解释的好处是没有制作文件的自由。)放弃我的项目,这是你工作的地方。

您至少将gopath设置为godev,但您可能希望gopath从非您的外部包的路径开始。例如,我使用的gopath是/goext:/godev

您在main.go中的导入现在应该是"github.com/user/project/utils",这是正确的。

不要担心Go-Get或任何Go命令会覆盖您的文件或破坏版本控制。通过gopath,他们可以看到您在哪里工作,并且知道版本控制是如何工作的。


如果您想将代码保存在本地版本存储库中,只需将代码放在gopath中即可。

gopath接受多个路径。在Linux上

1
GOPATH=$HOME/go:$HOME/prj/foo

所以,您可以在$home/go/src/中安装第三方软件包。而且,您可以将代码控制在$home/prj/foo/src中。

参考号:go help gopath


很多人说应该绝对使用路径来构建项目结构和导入:

1
import"github.com/user/utils"

但这可能会将您的项目限制在单个回购(Github)中。我想用相对路径:

1
  import"./utils"

我找不到办法,我在这里提出一个问题:如果Go项目包将托管在不同的Repo(Github&SourceForge),则如何组织该项目包