Contributions to other's repositories

So here is a problem I’ve got.

I want to contribute to Mary’s project somelib. It lives on github and gets imported as So far so good.

I fork the project on github into and update the way a particular bit works. After much success (well, it builds) I go to test it and my changes don’t seem to be working. I stare at it, determine nothing is wrong and start throwing fmt.Printfs at the wall. They don’t show up. Wat.

At this point it’s probably obvious what is going on – my code is cloned into $GOPATH/src/ (because that’s the place it should live) but it’s Mary’s project so all the code imports and none of the changes I made to subpkg are getting pulled in. Makes sense.

This seems to suggest a kind of broken workflow for contributing to other people’s code:

  1. Fork on github
  2. mkdir $GOPATH/src/
  3. cd $GOPATH/src/
  4. git clone
  5. Make changes, push, send PR

That “works” … except now I’m checking my code out into And while that’s kind of reasonable for one project that I may want to contribute to as soon as I get involved in several it’s kind of a disaster to remember which I’ve currently got overlaid on top of the actual released versions (since I can no longer rely on path to tell me where they come from).

Is there a better way I’m just not seeing or some kind of tooling / virtualenv thing that makes this not terrible?

I think you have the essence of it.

For contributing patches and pull requests on a package, you work in that package’s import path - src/ Add git remotes as appropriate, perhaps origin pointing to your fork and mary pointing to the original. Don’t worry about the fact that Mary appears in the path name. This may go against your vanity, but it really doesn’t matter and is quite common. For example I work on Syncthing in src/, but my fork is of course

For long lived forks, update your code to import and carry on as always.

For the in between things when you need a patch to the upstream, you don’t want to maintain a fork, and you need reliable builds for something that depends on this package - use vendoring.


With the Go 1.5 vendor experiment, you could have your code at $GOPATH/src/ and then just symlink it to $whateverprojectthatusesalib/vendor/

That way you could code in your own fork, and all is well, but you can test it out without modifying code in the project.


I’ve used Glide to great success for this use case. It supports a feature to alias one vendored package to another. So, you would add a dependency on your forked somelib to glide.yaml. In that same declaration you can tell Glide to alias it to some other name, specifically the original repo you’ve forked. Therefore the your imports don’t need to change but they will actually import your forked version.

Once your PR/fix is merged, you just update the config to point to the main repo and remove the import of your fork.

1 Like

I could be misunderstanding the question, but at least in the case of the repo being Git-based, I’ve accomplished this by manipulating remotes. I set the original to be upstream and my fork to be origin. This way keeps all internal import paths the way they are, lets you work on your changes and easily PR, etc etc. Here’s an alias I made to make it easier to set up a GitHub project for work:

Get hub - it’s a great CLI tool for interacting with github. Pretty sure go get Just Works™

Generally, if you’re going to work on someone’s go code, you’ll already have their code in your GOPATH. If not, go get their code so it’s in the right spot in your GOPATH.

Now, with hub, it’s easy. Just go to that directory and do hub fork. That’ll fork their project into your username on github, and add a remote for the fork with your github username. bam, done. When you make a new branch, remember to push -u <your-gh-username> and further pushes for that branch will always go to your fork.

Furthermore, when you’re done with your branch, you can do hub pull-request and it’ll automatically make a PR versus the original repo from your branch.


This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.