假设您在github.com/someone/repo
有一个存储库,并将其分叉到github.com/you/repo
。你想使用你的fork代替主repo,所以你做了一个
go get github.com/you/repo
现在这个仓库中的所有导入路径都将“损坏”,这意味着,如果存储库中有多个包通过绝对URL互相引用,它们将引用源,而不是fork。
有没有更好的方法将其手动克隆到正确的路径?
git clone git@github.com:you/repo.git $GOPATH/src/github.com/someone/repo
答案 0 :(得分:74)
github.com/someone/repo
分叉到github.com/you/repo
go get github.com/someone/repo
cd "$(go env GOPATH)/src"/github.com/someone/repo
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
答案 1 :(得分:19)
解决问题的一种方法是由Ivan Rave和http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html建议 - 分叉的方式。
另一个是解决 golang 行为。当您go get
时, golang 以与存储库URI中相同的名称布局您的目录,这就是麻烦开始的地方。
相反,如果您发布自己的git clone
,则可以将存储库克隆到原始存储库之后的路径上的文件系统中。
假设原始存储库位于github.com/awsome-org/tool
并且您将其分配到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 remote为awesome-you
。 awesome-org
的所有导入都会通过您刚刚创建的目录(即您当地的工作集)进行重新调整。
更详细信息,请参阅我的博文:Forking Golang repositories on GitHub and managing the import path
编辑:固定目录路径
答案 2 :(得分:5)
如果您的前叉只是临时的(即您打算将其合并),那么只需在原地进行开发,例如在$GOPATH/src/launchpad.net/goamz
中。
然后使用版本控制系统的功能(例如git remote
)使上游存储库成为您的存储库而不是原始存储库。
这使得其他人更难以将您的存储库与go get
一起使用,但更容易将其集成到上游。
事实上,我在lp:~nick-craig-wood/goamz/goamz
有一个goamz的存储库,我就是以这种方式开发的。也许作者有一天会合并它!
答案 3 :(得分:3)
对此的答案是,如果您使用多个包分叉回购,则需要重命名所有相关的导入路径。这在很大程度上是一件好事,因为您已经分配了所有这些包,导入路径应该反映这一点。
答案 4 :(得分:3)
这是一种适用于所有人的方法:
使用github分叉到“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,它会保留历史记录,而构建工具可以理解它。
答案 5 :(得分:2)
为了自动化这个过程,我写了一个小脚本。您可以在我的blog上找到更多详细信息,以添加&#34; gofork&#34;等命令。对你的打击。
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
答案 6 :(得分:2)
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"
这解决了所有我在尝试自己解决此问题时遇到的所有问题。
答案 7 :(得分:1)
如果您使用的是go modules。您可以使用replace
指令。
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 master
您还可以在分支的存储库上创建一个release标签并使用它。
答案 8 :(得分:0)
在您的Gopkg.toml
文件中,在下面添加这些代码块
[[constraint]]
name = "github.com/globalsign/mgo"
branch = "master"
source = "github.com/myfork/project2"
因此它将使用分叉的project2
代替github.com/globalsign/mgo
答案 9 :(得分:0)
除了克隆到特定位置之外,您还可以在任意位置克隆。 然后,您可以运行这样的命令,以使Go引用本地版本:
go mod edit -replace github.com/owner/repo=../repo
答案 10 :(得分:0)
现代答案(至少达到 1.15 或更高)。
go mod init github.com/theirs/repo
创建一个显式的 init arg,它是原始包名称。如果您不包含 repo 名称,它将假定 gopath 中的那个。但是当你使用 go 模块时,它们不再关心它们在磁盘上的位置,或者 git 实际上从哪里提取依赖项。
答案 11 :(得分:-1)
您可以使用命令go get -f
为您创建一个分叉的仓库