Reputation:
Suppose you have a repository at github.com/someone/repo
and you fork it to github.com/you/repo
. You want to use your fork instead of the main repo, so you do a
go get github.com/you/repo
Now all the import paths in this repo will be "broken", meaning, if there are multiple packages in the repository that reference each other via absolute URLs, they will reference the source, not the fork.
Is there a better way as cloning it manually into the right path?
git clone [email protected]:you/repo.git $GOPATH/src/github.com/someone/repo
Upvotes: 150
Views: 46759
Reputation: 7886
Since Go 1.18, you can use Go Workspace for this use case.
Run the command
$ go work init path-to-your-fork path-to-your-app-module
or directly edit
go.work
go 1.18
use (
./path-to-your-fork
./path-to-your-app-module
)
The paths here refer to the location of the local copy in your computer.
Upvotes: 1
Reputation: 4784
If you are using go modules. You could use replace
directive
The
replace
directive allows you to supply another import path that might be another module located in VCS (GitHub or elsewhere), or on your local filesystem with a relative or absolute file path. The new import path from thereplace
directive is used without needing to update the import paths in the actual source code.
So you could do below in your go.mod file
module some-project
go 1.12
require (
github.com/someone/repo v1.20.0
)
replace github.com/someone/repo => github.com/you/repo v3.2.1
where v3.2.1
is tag on your repo. Also can be done through CLI
go mod edit -replace="github.com/someone/[email protected]=github.com/you/[email protected]"
Upvotes: 188
Reputation: 1437
The modern answer (go 1.15 and higher, at least).
go mod init github.com/theirs/repo
Make an explicit init arg that is the ORIGINAL package names. If you don't include the repo name, it will assume the one in gopath. But when you use go modules, they no longer care where they are on disk, or where git actually pulls dependencies from.
Upvotes: 0
Reputation: 1
Instead of cloning to a specific location, you can clone wherever you want. Then, you can run a command like this, to have Go refer to the local version:
go mod edit -replace github.com/owner/repo=../repo
https://golang.org/cmd/go#hdr-Module_maintenance
Upvotes: 3
Reputation: 1687
in your Gopkg.toml
file add these block below
[[constraint]]
name = "github.com/globalsign/mgo"
branch = "master"
source = "github.com/myfork/project2"
So it will use the forked project2
in place of github.com/globalsign/mgo
Upvotes: -5
Reputation: 1405
Here's a way to that works for everyone:
Use github to fork to "my/repo" (just an example):
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
Repeat each time when you make the code better:
git commit
git checkout enhancement
git cherry-pick <<commit_id>>
git checkout master
Why? This lets you have your repo that any go get
works with. It also lets you maintain & enhance a branch that's good for a pull request. It doesn't bloat git with "vendor", it preserves history, and build tools can make sense of it.
Upvotes: 3
Reputation: 1789
github.com/someone/repo
to 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
https://github.com/golang/go/wiki/PackageManagementTools
Upvotes: 85
Reputation: 11901
import
statements in your source code to point to the vendor folder, (not including the vendor/
prefix). E.g. vendor/bob/lib
=> import "bob/lib"
cd ~/go/src/github.com/myproj
mygithubuser=timabell
upstreamgithubuser=denisenkom
librepo=go-mssqldb
git submodule add "[email protected]:$mygithubuser/$librepo" "vendor/$upstreamgithubuser/$librepo"
This solves all the problems I've heard about and come across while trying to figure this out myself.
Upvotes: 1
Reputation: 957
To automate this process, I wrote a small script. You can find more details on my blog to add a command like "gofork" to your 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
Upvotes: -1
Reputation: 9404
One way to solve it is that suggested by Ivan Rave and http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html -- the way of forking.
Another one is to workaround the golang behavior. When you go get
, golang lays out your directories under same name as in the repository URI, and this is where the trouble begins.
If, instead, you issue your own git clone
, you can clone your repository onto your filesystem on a path named after the original repository.
Assuming original repository is in github.com/awsome-org/tool
and you fork it onto github.com/awesome-you/tool
, you can:
cd $GOPATH
mkdir -p {src,bin,pkg}
mkdir -p src/github.com/awesome-org/
cd src/github.com/awesome-org/
git clone [email protected]:awesome-you/tool.git # OR: git clone https://github.com/awesome-you/tool.git
cd tool/
go get ./...
golang is perfectly happy to continue with this repository and doesn't actually care some upper directory has the name awesome-org
while the git remote is awesome-you
. All import for awesome-org
are resovled via the directory you have just created, which is your local working set.
In more length, please see my blog post: Forking Golang repositories on GitHub and managing the import path
edit: fixed directory path
Upvotes: 21
Reputation: 54117
If your fork is only temporary (ie you intend that it be merged) then just do your development in situ, eg in $GOPATH/src/launchpad.net/goamz
.
You then use the features of the version control system (eg git remote
) to make the upstream repository your repository rather than the original one.
It makes it harder for other people to use your repository with go get
but much easier for it to be integrated upstream.
In fact I have a repository for goamz at lp:~nick-craig-wood/goamz/goamz
which I develop for in exactly that way. Maybe the author will merge it one day!
Upvotes: 4
Reputation: 25245
The answer to this is that if you fork a repo with multiple packages you will need to rename all the relevant import paths. This is largely a good thing since you've forked all of those packages and the import paths should reflect this.
Upvotes: 1