Pivotal Engineering Journal

Technical articles from Pivotal engineers.

Git pushInsteadOf

Best practices for Git on mixed-source teams

Posted on by
Categories:   git   
Edit this post on GitHub.

Here’s how to set up your workstation for easy access to both open-source and closed-source git repositories.


The problem(s)

Are you on a team that works with both public and private repositories on GitHub? Do you use SSH authentication? (If not, you should.)

If so, you may have encountered one of these problems…

Problem 1: You can’t pull an open-source project

When you try to pull an open-source repo

cd my-public-repo
git pull

it ought to just work, regardless of whether you’ve added your SSH key. But instead, you might see

Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

That’s an open-source repo: anyone should be able to pull it, right?

Problem 2: You’re prompted for username + password, but you prefer SSH

You add your SSH key and try to pull a private repo

ssh-add -t 1H /Volumes/my-ssh-key/id_rsa
cd my-private-repo
git pull

You want it to authenticate via SSH. But instead you see:

Username for 'https://github.com': myusername
Password for 'https://myusername@github.com':

Whoops.


The fix

Here’s a simple 3-part workflow to correct both of the problems above.

Part 1: Set a global pushInsteadOf override

In your global git configuration file, ~/.gitconfig, add this section:

[url "git@github.com:"]
  pushInsteadOf = https://github.com/
  pushInsteadOf = git://github.com/

This ensures that pushes will always use SSH authentication, even if the remote URL specifies https:// or git://

Part 2: Public repos use https remote

In the local checkout for each public repo, edit the .git/config so that the remote uses https:

[remote "origin"]
  url = https://github.com/myusername/my-public-repo

This way, you can pull public remotes without needing to authenticate.

If you’re cloning a public repo for the first time, follow the same pattern

git clone https://github.com/myusername/my-public-repo

Part 3: Private repos use SSH remote

In the local checkout for each private repo, edit the .git/config file to use SSH authentication:

[remote "origin"]
  url = git@github.com:myusername/my-private-repo

This ensures that git pulls will use your SSH key instead of prompting you for a username and password.

If you’re cloning a private repo for the first time, follow the same pattern

git clone git@github.com:myusername/my-private-repo

That’s it!


Conclusion

Follow the steps above whenever you’re working with a mixture of open-source and closed-source repositories.

If your open-source project uses git submodules, be sure to use HTTPS for the submodule references too. This way, anyone can easily pull and checkout all your submodules, even if they can’t authenticate against the remote.


Further Reading