Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using forked package import in Go

Tags:

go

People also ask

Is forking better than cloning?

It is a better option to fork before clone if the user is not declared as a contributor and it is a third-party repository (not of the organization). Forking is a concept while cloning is a process. Forking is just containing a separate copy of the repository and there is no command involved.

Can I create a pull request from a forked repo?

You can create a pull request to propose changes you've made to a fork of an upstream repository. Anyone with write access to a repository can create a pull request from a user-owned fork.

What is a forked package?

In software engineering, a project fork happens when developers take a copy of source code from one software package and start independent development on it, creating a distinct and separate piece of software.


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 the replace 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 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

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]"

To handle pull requests

  • fork a repository github.com/someone/repo to github.com/you/repo
  • download original code: go get github.com/someone/repo
  • be there: cd "$(go env GOPATH)/src"/github.com/someone/repo
  • enable uploading to your fork: git remote add myfork https://github.com/you/repo.git
  • upload your changes to your repo: git push myfork

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

To use a package in your project

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


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


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!


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.


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.


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