On this page:
I seemed to spend a crazy amount of time trying to work out how to change access to a Git repository (repo) from HTTPS to SSH to avoid password prompts when pushing changes to BitBucket and GitHub. Here, I outline how to do it on Mac OS X, partly to remind myself how to do it in the future, partly to collate all the infomation on the internet about it and partly in the hope that someone else might find it useful.
This rigmarole needs to be done on each computer you intend to access your Git repo with for each repo you have that you want to access by SSH rather than by HTTPS.
Change the remote path of the repo
This is how you tell your Git server how you want to access it.
Open Terminal or your command-line app of choice and navigate to your repo’s directory:
cd ~/projects/reponame
then check to see what you have on your server already:
git remote -v
You should see a pair of entries for each remote repo (I once had origin and origin2, but that’s another story): one for fetch, which includes pull, and one for push:
origin https://[email protected]/username/reponame.git (fetch) origin https://[email protected]/username/reponame.git (push)
This example shows a repo on BitBucket; GitHub is similar. You can see that the URLs include the https:// protocol. This is what we want to change. Type the following for BitBucket:
git remote set-url origin [email protected]:username/reponame.git
For GitHub, replace bitbucket.org with github.com. Then check what’s there again:
git remote -v
This time, you’ll see something like this:
origin [email protected]:username/reponame.git (fetch) origin [email protected]:username/reponame.git (push)
Troubleshooting
Error: Could not resolve hostname
You might get this error:
ssh: Could not resolve hostname github.com:username: nodename nor servname provided, or not known fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
If you do, check the output from git remote -v carefully. See if the SSH URL is prefixed with ssh://, like this:
origin ssh://[email protected]:username/reponame.git (fetch) origin ssh://[email protected]:username/reponame.git (push)
If it is, run set-url again, making sure to exclude the ssh:// part of the URL. Run git remote -v again and check the output. You may find that only fetch has changed — if so, the next section should help.
Only fetch changes; push stays the same
If the fetch URL has changed but the push URL has not, like this:
origin [email protected]:username/reponame.git (fetch) origin https://[email protected]/username/reponame.git (push)
or like this:
origin [email protected]:username/reponame.git (fetch) origin ssh://[email protected]:username/reponame.git (push)
you’ll need to do the push separately by using the --push option:
git remote set-url --push origin [email protected]:username/reponame.git
You don’t need to do anything further for pull because it does what fetch does (because pull is equivalent to fetch then merge).
I don’t know why it works for some cases but not other ones. It happened for me when I got the could not resolve hostname error above and ran set-url again. It seems that the set-url command is applied to both fetch and push when changing the protocol, but when keeping the (SSH) protocol the same, it only updates fetch.
If you have a SSH key already for the computer/device you’re using, you’re all set. If not, read on.
Create a SSH key
If you don’t already have a SSH key for BitBucket and/or GitHub on the particular device you’re using, you’ll need to create one for each service that you use and on each device that you will use to access your repos:
- set up a SSH key for BitBucket on macOS (steps 1–2 for Git);
- create a SSH key for GitHub (step 1).
You’ll end up with two SSH keys, one private and one public, which you can see by running:
ssh-add -l
or you can list all the SSH keys you have by running:
ls ~/.ssh
which will output something like:
id_rsa id_rsa.pub
The key without the extension is the private key and the key with the .pub extension is the public key. The private key stays on your computer and the public key is uploaded onto the server.
BitBucket recommend you keep the default key name [id_rsa] unless you have a reason to change it
. However, I’d recommend using something descriptive, like bitbucket_id_rsa so you know what it’s for later and to avoid accidentally overwriting the key if you create one for BitBucket, one for GitHub, one for your web server and so on.
Add the public SSH key to your remote Git server
The public SSH key (the one with the .pub extension) is for the server, so you need to upload it to your account on the relevant one:
Add the private SSH key to your keychain
If you don’t add the SSH key to your keychain, you’ll have to keep entering the passphrase you set up when creating the SSH key.
- Start the SSH agent in the background:
eval $(ssh-agent)
which gives you an agent pid:
Agent pid: 12345
- Add the private SSH key (the one with no extension) to your keychain; the -K option is Mac-specific and is what tells your Mac to add it to the keychain as well as wherever else it adds it to:
ssh-add -K ~/.ssh/github_id_rsa
- For MacOS Sierra onwards, you must add the SSH key file to the ~/.ssh/config file so you don’t have to call the previous command every time you restart your Mac. This also seems to be what makes the whole thing work with Sourcetree.
- Create a config file in your SSH keys directory, if there isn’t one already (you can check by using ls ~/.ssh):
nano ~/.ssh/config
I prefer the Nano editor if I’m going to use a command-line editor, but you can use Vim or Emacs or whatever you like, of course.
- Add an entry for Host * (where * means any host, I presume) stating that the keychain is to be used and the keys are to be added to said keychain. An IdentityFile entry in your ~/.ssh/config file is needed for each SSH key:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/bitbucket_id_rsa
IdentityFile ~/.ssh/github_id_rsaIf you don’t add this config file, you’ll have to run ssh-add -K ~/.sshkeyname every time you restart your Mac.
- Create a config file in your SSH keys directory, if there isn’t one already (you can check by using ls ~/.ssh):
- You should now be able to use Git without having to use your password all the time.
Test it works
You can type in the terminal for a GitHub repo:
ssh -T [email protected]
to get the following message:
Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.
For a BitBucket repo, type:
ssh -T [email protected]
to get the following message:
logged in as <username>. You can use Git or hg to connect to Bitbucket. Shell access is disabled.
In your terminal, assuming your repo is up-to-date, you can test everything works by typing the following:
git fetch
which should give no output if it works. Typing:
git push
should result in an up-to-date message:
Everything up-to-date
If that works, try pressing Fetch in Sourcetree then Push. If you get no errors, you’re good to go.
Troubleshooting
Warning: Permanently added the RSA host key for IP address ‘xxx.xxx.xxx.xxx’ to the list of known hosts
This warning seems to be merely an informative message. You shouldn’t see it again and you can quite happily ignore it.
Error: Permission denied
If you get this error, especially in Sourcetree:
[email protected]: Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
then check that you have spelt everything correctly and followed every step.
Bibliography
Listed in no particular order, the following links helped me get all this working and/or contain more information that might help you understand what’s going on:
- Generating a new SSH key and adding it to the ssh-agent (GitHub)
- Adding a new SSH key to your GitHub account (GitHub)
- How can I remove an SSH key? (Stack Overflow)
- Adding a Private Key to Your Mac OSX Keychain (HPCC)
- Why eval the output of ssh-agent? (Stack Exchange)
- Adding your SSH key to the ssh-agent (GitHub)
- Changing Git remote URL updates fetch but not push (Stack Overflow)
- Difficulties with ssh-agent in macOS Sierra (Reddit)
- Testing your SSH connection (GitHub)
- Generating a new SSH key and adding it to the ssh-agent (GitHub)
- How can I permanently add my SSH private key to Keychain so it is automatically available to ssh? (Stack Exchange)
- How can I use my existing default ssh key with SourceTree? (Atlassian)
- SourceTree SSH options on OS X (superuser)
- How often should an SSH key pair be changed? (Stack Exchange)
- Where are my private/public SSH keys on UNIX? (superuser; actually relates to Mac OS)
- How to Add a Private Key to Your Mac OS X Keychain (Dev Dustin).
NB Server does not respond since 25 August 2022; original URL: http://devdustin.com/2015/10/22/add-private-key-mac-os-x-keychain/ - Changing Git remote URL updates fetch but not push (Stack Overflow)
- Adding a new SSH key to your GitHub account (GitHub)
- Configure SSH and two-step verification (BitBucket)
- Set up an SSH key (Bitbucket)
- Where are my private/public SSH keys on UNIX? (superuser)
I am very grateful to all the people who contributed to getting this information out there for me to find. Thank you.
Update: I’m delighted to hear that collating this information has helped other people sort out their configurations – thank you for letting me know in the comments 🙂
thanks, it helped me!
I’m so pleased to hear that! Glad I could be of help and thanks for letting me know 🙂
Thank you, your article was very helpful for me (and it worked!)
That’s great, Dieter! I’m glad I could help someone else 🙂 Thank you for taking the time to tell me.
Thank you so much, I wanted to “migrate” my repos to ssh, and this was exactly what I was looking for!
I’m delighted to hear this, Francesco. Thank you for letting me know!
Thanks, this is still useful!
My server changed IP address, so I was looking to fix “Warning: the RSA host key for ‘example.com’ differs from the key for the IP address ‘xxx.xxx.xxx.xxx'”.
I deleted both the ‘offending’ and ‘matching’ lines from the ~/.ssh/known_hosts file and that allowed the system to ‘permanently add the RSA host’.
Hi John, I’m really pleased I could help you out! Thanks for taking the time to comment.
Thanks! This is STILL very useful!
I’m glad 🙂
Thank you
thank you very much!! super helpful
I’m so happy I helped you! Thanks for taking the time to comment 🙂
Thanks – this was really useful – Github has changed up their authentication so I’ve had to move away from password on CLI and ssh is the lightest way to go. Cheers
Hi Ingram, you’re most welcome! I’m really pleased I could help you solve your problem. Thanks for letting me know 🙂
I’ve recently come across this situation myself in a repo I hadn’t used for a while. I wasn’t sure how to use the application password they recommend with iTerm, but then I remembered your comment about using SSH instead. Thank you!