go get private dependency with a git subtree

Travis is a great CI tool that has pretty good support for Go builds. Working with Go is reasonably straight forward because you can get most things you need with a simple go get. That said, I ran into an issue today trying to include a dependency on a private repo on Github. So I’ve decided to write down how I solved it in case anybody else runs into the same issue.


I ended up solving the issue by adding a new user to my Github organization and giving them read only access to the repository I wanted to subtree link to. I used https with a token that avoids having to be prompted for a password. Travis handles the subtree pull, so provided the repository still builds locally after pulling a subtree in, then Travis shouldn’t have an issue with it either.


I am not a git Jedi. This article is not a general explanation of git subtrees. There are plenty of articles out there explain in varying detail why and how to use them.

Also, please be sensible when setting the access privileges for this user. I’m assuming that read only access does not pose too great a security risk for my application. This may not be the case for everybody.

Limitations of go get

When all is said and done, go get is a pretty simple tool. It’s a really easy way of pulling in third party dependencies into your $GOPATH. This simplicity also exposes its limitations. It doesn’t have great support for dealing with non-public repositories on the major code hosting sites. So instead of trying to fight go get, I thought I’d let git solve the issue.


To generate the token, substitute READ_ONLY_USER with the username of the new user you created:

$ curl -u 'READ_ONLY_USER' -d '{"scopes":["repo"]}' \
Enter host password for user 'READ_ONLY_USER':
  "id": 5548862,
  "url": "https://api.github.com/authorizations/5548862",
  "app": {
    "name": "GitHub API",
    "url": "http://developer.github.com/v3/oauth/#oauth-authorizations-api",
    "client_id": "00000000000000000000"
  "token": "1d4fba78b888968e913a22028ae982042dfd0aa3",
  "note": null,
  "note_url": null,
  "created_at": "2014-02-03T15:57:14Z",
  "updated_at": "2014-02-03T15:57:14Z",
  "scopes": [

If this the call is successful, you should get a blob of JSON back with the token in it. In this example, the token is 1d4fba78b888968e913a22028ae982042dfd0aa3.

To verify that this token will work with the target repo, substitute MY_ORGANIZATION for the name of your Github organization and MY_REPO for the repo:

$ curl -I -H "Authorization: bearer 1d4fba78b888968e913a22028ae982042dfd0aa3" \

If all is well, this should return an HTTP 200.

Now you can add the link to the subtree to your dependent source tree. In this example, substitute the PATH for the relavtive path to where you want your subtree link to sit:

$ git subtree add --prefix PATH --squash \
  https://1d4fba78b888968e913a22028ae982042dfd0aa3:x-oauth-basic@github.com/MY_ORGANIZATION/MY_REPO \
git fetch https://1d4fba78b888968e913a22028ae982042dfd0aa3:x-oauth-basic@github.com/MY_ORGANIZATION/MY_REPO master
warning: no common commits
remote: Counting objects: 22, done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 22 (delta 4), reused 20 (delta 2)
Unpacking objects: 100% (22/22), done.
From https://github.com/MY_ORGANIZATION/MY_REPO
 * branch            master     -> FETCH_HEAD
Added dir 'PATH'

After you’re happy with the effects of adding the subtree to your repository, you can push this change out to source control for Travis to build:

$ git push


Setting the read only access correctly for the subtree user is down to you. You need to know how to set this up properly in the Github UI. If you don’t do this properly, you might end up publishing stronger credentials than you intended to.

  1. Unless I didn’t read the documenation on Github OAuth scoping properly, there doesn’t seem to be a scope that you can use to give to an existing user read-only access to a private repo.

comments powered by Disqus