127

假设您有一个存储库,github.com/someone/repo并且您将其 fork 到github.com/you/repo. 你想使用你的 fork 而不是主 repo,所以你做一个

go get github.com/you/repo

现在这个 repo 中的所有导入路径都将被“破坏”,这意味着,如果存储库中有多个包通过绝对 URL 相互引用,它们将引用源,而不是 fork。

有没有更好的方法将其手动克隆到正确的路径中?

git clone git@github.com:you/repo.git $GOPATH/src/github.com/someone/repo
4

12 回答 12

135

如果您使用的是go modules。你可以使用replace指令

replace指令允许您提供另一个导入路径,该路径可能是位于 VCS(GitHub 或其他地方)中的另一个模块,或者位于具有相对或绝对文件路径的本地文件系统上。使用指令中的新导入路径,replace无需更新实际源代码中的导入路径。

因此,您可以在 go.mod 文件中执行以下操作

module github.com/yogeshlonkar/openapi-to-postman

go 1.12

require (
    github.com/someone/repo v1.20.0
)

replace github.com/someone/repo => github.com/you/repo v3.2.1

v3.2.1您的仓库中的标签在哪里。也可以通过 CLI 完成

go mod edit -replace="github.com/someone/repo@v0.0.0=github.com/you/repo@v1.1.1"
于 2019-06-27T14:01:29.733 回答
86

处理拉取请求

  • fork 一个仓库github.com/someone/repogithub.com/you/repo
  • 下载原代码:go get github.com/someone/repo
  • 在那里:cd "$(go env GOPATH)/src"/github.com/someone/repo
  • 启用上传到您的 fork:git remote add myfork https://github.com/you/repo.git
  • 将您的更改上传到您的仓库:git push myfork

http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html

在项目中使用包

https://github.com/golang/go/wiki/PackageManagementTools

于 2015-03-20T07:59:00.060 回答
20

解决它的一种方法是 Ivan Rave 和http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html提出的方法——分叉的方式。

另一种是解决golang行为。当 you 时go getgolang 会以与存储库 URI 相同的名称来布置目录,这就是麻烦开始的地方。

相反,如果您发布自己的git clone,则可以将您的存储库克隆到以原始存储库命名的路径上的文件系统上。

假设原始存储库在github.com/awsome-org/tool并且您将其 fork 到github.com/awesome-you/tool,您可以:

cd $GOPATH
mkdir -p {src,bin,pkg}
mkdir -p src/github.com/awesome-org/
cd src/github.com/awesome-org/
git clone git@github.com:awesome-you/tool.git # OR: git clone https://github.com/awesome-you/tool.git
cd tool/
go get ./...

golang非常乐意继续使用这个存储库,并且实际上并不关心某些上层目录的名称awesome-org,而 git 远程是awesome-you. 所有导入awesome-org都通过您刚刚创建的目录进行解析,该目录是您的本地工作集。

更详细的内容,请参阅我的博文:在 GitHub 上分叉 Golang 存储库并管理导入路径

编辑:固定目录路径

于 2015-11-24T13:59:51.740 回答
5

如果您的分叉只是临时的(即您打算将其合并),那么只需在原地进行开发,例如在$GOPATH/src/launchpad.net/goamz.

然后,您使用版本控制系统的功能(例如git remote)将上游存储库而不是原始存储库设为您的存储库。

它使其他人更难使用您的存储库,go get但更容易将其集成到上游。

事实上,我有一个 goamz 存储库lp:~nick-craig-wood/goamz/goamz,我正是以这种方式开发的。也许有一天作者会合并它!

于 2013-01-15T22:34:43.440 回答
3

这是一种适用于所有人的方法:

使用 github fork 到“my/repo”(只是一个例子):

go get github.com/my/repo
cd ~/go/src/github.com/my/repo
git branch enhancement
rm -rf .
go get github.com/golang/tools/cmd/gomvpkg/…
gomvpkg <<oldrepo>> ~/go/src/github.com/my/repo
git commit

每次使代码更好时重复:

git commit
git checkout enhancement
git cherry-pick <<commit_id>>
git checkout master

为什么?这使您可以拥有任何go get可以使用的存储库。它还允许您维护和增强对拉取请求有益的分支。它不会用“供应商”使 git 膨胀,它保留了历史,并且构建工具可以理解它。

于 2017-08-24T03:33:20.237 回答
2

对此的答案是,如果你 fork 一个包含多个包的 repo,你将需要重命名所有相关的导入路径。这在很大程度上是一件好事,因为您已经分叉了所有这些包,并且导入路径应该反映这一点。

于 2013-01-14T21:34:13.127 回答
1

您可以克隆到任何您想要的位置,而不是克隆到特定位置。然后,您可以运行这样的命令,让 Go 引用本地版本:

go mod edit -replace github.com/owner/repo=../repo

https://golang.org/cmd/go#hdr-Module_maintenance

于 2020-11-21T20:49:12.507 回答
0

现代答案(至少 1.15 或更高版本)。

go mod init github.com/theirs/repo

制作一个明确的 init 参数,它是原始包名称。如果您不包含 repo 名称,它将假定为 gopath 中的名称。但是当你使用 go 模块时,它们不再关心它们在磁盘上的位置,或者 git 实际从哪里提取依赖项。

于 2021-06-17T23:46:04.990 回答
0

一起使用 vendoring 和子模块

  1. 在 github 上 fork 库(本例中为 go-mssqldb)
  2. 添加一个子模块,将您的 fork 克隆到您的供应商文件夹中,但具有上游 repo 的路径
  3. 更新import源代码中的语句以指向供应商文件夹(不包括vendor/前缀)。例如vendor/bob/lib=>import "bob/lib"

例如

cd ~/go/src/github.com/myproj

mygithubuser=timabell
upstreamgithubuser=denisenkom
librepo=go-mssqldb

git submodule add "git@github.com:$mygithubuser/$librepo" "vendor/$upstreamgithubuser/$librepo"

为什么

这解决了我在尝试自己解决这个问题时所听到和遇到的所有问题。

  • lib 中的内部包引用现在可以工作,因为上游的路径没有改变
  • 重新签出您的项目是有效的,因为子模块系统在正确的提交时从您的 fork 中获取它,但在上游文件夹路径中
  • 您不必知道手动破解路径或弄乱 go 工具。

更多信息

于 2018-08-16T18:07:29.627 回答
-1

您可以使用命令go get -f为您获取一个分叉的 repo

于 2020-01-22T08:37:48.710 回答
-1

为了自动化这个过程,我写了一个小脚本。您可以在我的博客上找到更多详细信息,以将“gofork”之类的命令添加到您的 bash。

function gofork() {
  if [ $# -ne 2 ] || [ -z "$1" ] || [ -z "$2" ]; then
    echo 'Usage: gofork yourFork originalModule'
    echo 'Example: gofork github.com/YourName/go-contrib github.com/heirko/go-contrib'
    return
  fi
   echo "Go get fork $1 and replace $2 in GOPATH: $GOPATH"
   go get $1
   go get $2
   currentDir=$PWD
   cd $GOPATH/src/$1
   remote1=$(git config --get remote.origin.url)
   cd $GOPATH/src/$2
   remote2=$(git config --get remote.origin.url)
   cd $currentDir
   rm -rf $GOPATH/src/$2
   mv $GOPATH/src/$1 $GOPATH/src/$2
   cd $GOPATH/src/$2
   git remote add their $remote2
   echo Now in $GOPATH/src/$2 origin remote is $remote1
   echo And in $GOPATH/src/$2 their remote is $remote2
   cd $currentDir
}

export -f gofork
于 2017-10-26T07:09:07.277 回答
-2

在您的Gopkg.toml文件中添加以下这些块

[[constraint]]
  name = "github.com/globalsign/mgo"
  branch = "master"
  source = "github.com/myfork/project2"

所以它将使用分叉project2代替github.com/globalsign/mgo

于 2019-08-21T09:54:06.243 回答