Skip to content

`go get` for public and private repositories

Created by: mattes

Right now it is not possible to use go get with private repositories. Only public repositories are supported.

Public repository: (this works because of the go-import meta tag)

curl http://example.com/mattes/public_repo?go-get=1
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<meta content='example.com/mattes/public_repo git http://example.com/mattes/public_repo.git' name='go-import'>
<meta content='GitLab Community Edition' name='description'>
[...]

Private repository: (this fails because it is missing the go-import meta tag, instead it is trying to redirect me to the sign in page)

curl http://example.com/mattes/private_repo?go-get=1
<html><body>You are being <a href="http://example.com/users/sign_in">redirected</a>.</body></html>

To make private repositories work, it should include the go-import meta tag even for private repositories and not redirect. My patch does exactly that. Depending on the user-agent (go get sends Go 1.1 package http as user-agent) nginx will always render a html page with the correct go-import meta tag.

It's not a problem to always render the go-import meta tag for go get user-agents, because go get will fail in the second step anyway, if the repo doesn't exist. We don't really expose any information about the existence of a repository neither.

With this patch sth like go get example.com/mattes/public_repo or go get example.com/mattes/private_repo works as expected. The latter one will ask for user credentials in the terminal, if there is no ~/.netrc file given. Github uses OAuth tokens here, Gitlab wants you to use your username/password combination. (Is it possible to use the private token?).

An example ~/.netrc could look like:

machine example.com login mattes password abc12356789

With this information in ~/.netrc the command go get example.com/mattes/private_repo won't ask for user credentials anymore.


A different approach might be to add a router constraint in config/routes.rb depending on the user-agent and then to render a html page here. I like the nginx approach more though.


If you do sth like go get example.com/mattes/private_repo.git (note the suffix .git) go get will use SSH instead of HTTPS. (I read that go get only uses HTTP, but I guess that info is outdated.). So if you added your public key to Gitlab, you could just add to ~/.ssh/config:

# example.com
Host example.com
Hostname example.com
User git

... and be able to go get example.com/mattes/private_repo.git as well. Downside: go import paths will always have the .git sufix: example.com/mattes/private_repo.git = ugly. This will work without my patch even today.

Merge request reports

Loading