Working with forks in Go
Tags: go, git
Published: 2018-01-09 09:59:01

---
title: Working with forks in Go
published: true
description: How to work with a forked 
cover_image: https://images.unsplash.com/photo-1513136917659-7306838e7d82?auto=format&fit=crop&w=1024&h=500&q=80
tags: go, golang, git
---

## Proper use of forks

![Dinglehopper me on GitHub](http://toldbydesign.com/wp-content/uploads/2013/01/Told-By-Design-Walt-Disney-Little-Mermaid-Scuttle-dinglehopper-fork.jpg)

Have you ever wanted to create a fork of a Go package you're using? Maybe you need to add a feature, specific to your use case, and there is no other way than to change it inside the code. Or maybe you want to fix a bug and submit a PR to an open-source project.

Whatever the case, Go, with its location-based import system, makes it hard to swap implementations of a package. If you try to just swap it into place, you'll most likely get an error along the lines of: `cannot use s (type "fork".SomeStruct) as type "original".SomeStruct in argument to SomeFunc` as soon as you pass your data types to a function defined in another file.

You can fix this with heavy refactoring — changing imports in your own code, and typecasting everything coming in from or going out to another package — but it's near impossible on a large project with many files.

[Type aliases](https://github.com/golang/proposal/blob/master/design/18130-type-alias.md) can help, but with a little bit of Git magic, you can seamlessly swap a package for your fork and keep hacking away.

## Fork and fix

![Not like that, no](https://i.imgur.com/zGskC7Y.jpg)

I won't go into detail on how to create a fork and submit a PR, GitHub has [extensive](https://guides.github.com/activities/forking/) [documentation](https://help.github.com/articles/fork-a-repo/) [on the subject](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). I'll just assume you've clicked the "Fork" button on GitHub, and now have your own repository containing a duplicate of the original source.

But as we've said, you can't just `go get` the forked repository, since all the import paths will be wrong. What we want is to have your local branch, inside your `GOPATH`, track your forked remote repository, instead of the original.

Let's start by adding a remote. From the package source path, type the following:

```shell
$ git remote add forked <remote repository url>
```

Then, let's make sure the local branch tracks the `forked` remote, and not the `origin` any more.

```shell
$ git branch -u forked/master
Branch master set up to track remote branch master from forked.
```

After this line, you can start committing and pushing to your own fork, and all Go packages relying on this repo will transparently use your own fork of the code.

This is useful, for example, if you're sure of a bugfix, as you can start working with the fixed version of the code without waiting for the changes to be merged upstream.

When you want to revert to tracking the origin, perhaps because your PR has been merged and you have deleted your fork, or because you need to use the original code for some other project, just type:

```shell
$ git branch -u origin/master
Branch master set up to track remote branch master from origin.

# Reset local branch to remote HEAD
$ git reset --hard origin/master
```

----

With these few lines of git, I can quickly fork and work on an open-source Go package. It's made my collaboration on open-source projects that much easier. What is your workflow for collaborating on open-source Go projects? Do you see any mistakes or caveats? Feel free to comment below!