在Go中使用forked包导入
假设您在在Go中使用forked包导入,go,Go,假设您在github.com/someone/repo上有一个存储库,然后将它转到github.com/you/repo。你想用你的叉子而不是主回购,所以你做了一个 go get github.com/you/repo 现在,此repo中的所有导入路径都将“断开”,这意味着,如果存储库中有多个包通过绝对URL相互引用,它们将引用源,而不是fork 有没有更好的方法手动将其克隆到正确的路径 git clone git@github.com:you/repo.git $GOPATH/src/git
github.com/someone/repo
上有一个存储库,然后将它转到github.com/you/repo
。你想用你的叉子而不是主回购,所以你做了一个
go get github.com/you/repo
现在,此repo中的所有导入路径都将“断开”,这意味着,如果存储库中有多个包通过绝对URL相互引用,它们将引用源,而不是fork
有没有更好的方法手动将其克隆到正确的路径
git clone git@github.com:you/repo.git $GOPATH/src/github.com/someone/repo
对此的答案是,如果您用多个包分叉回购,则需要重命名所有相关的导入路径。这在很大程度上是一件好事,因为您已经分叉了所有这些包,导入路径应该反映这一点。如果您的分叉只是临时的(即您打算将其合并),那么只需在原地进行开发,例如在
$GOPATH/src/launchpad.net/goamz中
然后,使用版本控制系统的功能(例如git remote
)使上游存储库成为您的存储库,而不是原始存储库
这使得其他人使用您的存储库时更难使用go-get
,但更容易将其集成到上游
事实上,我在lp:~nick craig wood/goamz/goamz
上有一个goamz的存储库,我就是这样开发的。也许有一天作者会合并它 处理拉取请求
- 将存储库
github.com/someone/repo
转移到github.com/you/repo
- 下载原始代码:
获取github.com/someone/repo
- 在那里:
cd“$(go env GOPATH)/src”/github.com/someone/repo
- 启用上载到您的fork:
git remote add myforkhttps://github.com/you/repo.git
- 将您的更改上载到您的回购:
git push myfork
在项目中使用包的步骤
解决这个问题的一个方法是伊万·雷夫(Ivan Rave)提出的,还有——分叉法
另一个是绕过golang行为。当您go-get
时,golang会以与存储库URI中相同的名称列出目录,这就是问题的根源
相反,如果您发布自己的git clone
,则可以将存储库克隆到文件系统上,路径以原始存储库命名
假设原始存储库位于github.com/awsome org/tool
中,并将其转移到github.com/awome 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 remote名为awesome you
。awesome org
的所有导入都通过您刚刚创建的目录解析,该目录是您的本地工作集
更多详细信息,请参阅我的博文:
编辑:固定目录路径以下是一种适用于所有人的方法:
使用github分叉到“my/repo”(只是一个示例):
获取github.com/my/repo
cd~/go/src/github.com/my/repo
git分支增强
rm-rf。
去github.com/golang/tools/cmd/gomvpkg/…
gomvpkg~/go/src/github.com/my/repo
git提交
每次改进代码时重复以下步骤:
git commit
git checkout enhancement
git cherry-pick <<commit_id>>
git checkout master
git提交
git签出增强
吉特樱桃采摘
切换到主分支
为什么??这可以让您拥有任何去获得的
都可以使用的回购协议。它还允许您维护和增强一个分支,该分支适合拉取请求。它不会用“供应商”来膨胀git,它保留了历史,构建工具可以理解它 为了自动化这个过程,我编写了一个小脚本。您可以在my上找到更多详细信息,以便在bash中添加类似“gofork”的命令
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
同时使用vendoring和子模块
在github上分叉lib(在本例中,转到mssqldb)
添加一个将您的分支克隆到您的分支中但具有上游回购路径的分支
更新源代码中的import
语句以指向供应商文件夹(不包括vendor/
前缀)。例如,供应商/bob/lib
=>导入“bob/lib”
例如。
为什么?
这解决了我自己在尝试解决这个问题时听到和遇到的所有问题
- 库中的内部包引用现在起作用,因为路径与上游的路径相同
- 项目的新签出是有效的,因为子模块系统在正确的提交位置(但在上游文件夹路径)从您的fork获取它
- 您不必知道如何手动破解路径或弄乱go工具
更多信息
如果您正在使用。你可以使用指令
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"
在Gopkg.toml
文件中,在下面添加这些块
[[constraint]]
name = "github.com/globalsign/mgo"
branch = "master"
source = "github.com/myfork/project2"
因此,它将使用forkedproject2
代替github.com/globalsign/mgo
您可以使用命令go get-f
获得forked repo而不是克隆到特定位置,您可以在任何地方进行克隆。
然后,您可以运行这样的命令,以便参考本地版本:
go mod edit -replace github.com/owner/repo=../repo
新fork中的任何导入路径都不会中断,因为在进行fork之前,这些路径尚未中断。很抱歉,让您失望,但事实并非如此。如果子包通过其绝对url在导入中引用,则此导入将在fork中中断(或至少引用错误的包)。例如。它有内部参考
[[constraint]]
name = "github.com/globalsign/mgo"
branch = "master"
source = "github.com/myfork/project2"
go mod edit -replace github.com/owner/repo=../repo