I find solution of this problem and try to explain it.
We should make change in both file ~/.ssh/config
and in ~/.gitconfig
Let's show.
1. Create keys
You will need one key for each different account you will use on either GitHub or BitBucket.
Whichever site you have more identities with determines how many keys you will need.
A single key can act both as a GitHub and BitBucket key but cannot be associated with more than one BitBucket or GitHub account.
If you already have created a key in ~/.ssh/id_rsa (the default location), you may use that in place of the ~/.ssh/msmith key in my examples or you can leave that key and add additional keys for the other identities.
Create the keys and ssh-add them (make sure to enter a secure password and do not just leave it blank)
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/key1_rsa -C "[email protected]"
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): ************
Enter same passphrase again:
Your identification has been saved in /Users/me/.ssh/key1_rsa.
Your public key has been saved in /Users/me/.ssh/key1_rsa.pub.
The key fingerprint is:
...
$ ssh-add ~/.ssh/key1_rsa
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/key2_rsa -C "[email protected]"
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): ************
Enter same passphrase again:
Your identification has been saved in /Users/me/.ssh/key2_rsa.
Your public key has been saved in /Users/me/.ssh/key2_rsa.pub.
The key fingerprint is:
...
$ ssh-add ~/.ssh/key2_rsa
2. Setup ~/.ssh/config
Create a file in ~/.ssh/config (if it does not already exist). You must make sure it is readable only by the owner and the group and public bits are set off.
touch ~/.ssh/config
chmod 600 ~/.ssh/config
We now need to add SSH configuration that specifies the github and bitbucket hostnames but with a suffix appended to qualify which key to use. We set the HostName to the correct github.com or bitbucket.org address.
Note: Linux users should either omit UseKeychain yes or add IgnoreUnknown UseKeychain (thanks soulofmischief)
~/.ssh/config
...
Host github.com-msmith
HostName github.com
UseKeychain yes
AddKeysToAgent yes
User git
IdentityFile ~/.ssh/msmith_rsa
IdentitiesOnly yes
Host bitbucket.org-msmith
HostName bitbucket.org
UseKeychain yes
AddKeysToAgent yes
User git
IdentityFile ~/.ssh/msmith_rsa
IdentitiesOnly yes
Host github.com-jblige
HostName github.com
UseKeychain yes
AddKeysToAgent yes
User git
IdentityFile ~/.ssh/jblige_rsa
IdentitiesOnly yes
Host bitbucket.org-jblige
HostName bitbucket.org
UseKeychain yes
AddKeysToAgent yes
User git
IdentityFile ~/.ssh/jblige_rsa
IdentitiesOnly yes
...
3. Add public keys to GitHub and BitBucket
Log into GitHub for each user and add the keys from ~/.ssh/xxxxx.pub to the respective users authorized SSH keys.
For more information on this see:
https://confluence.atlassian.com/bitbucket/set-up-an-ssh-key-728138079.html
or
https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account
4. Create key specific .gitconfig
You will need a single directory where all code that corresponds to a given key will be checked out to.
I prefer to keep all those directories in one directory in my home ~/src and I name them according to the account name associated with the key
mkdir -p ~/src/msmith
mkdir -p ~/src/jblige
In each directory put a .gitconfig file.
~/src/msmith/.gitconfig
...
[user]
email = [email protected]
[url "[email protected]"]
insteadOf = [email protected]
[url "[email protected]"]
insteadOf = [email protected]
~/src/jblige/.gitconfig
...
[user]
email = [email protected]
signingkey = ABCD1234
[url "[email protected]"]
insteadOf = [email protected]
[url "[email protected]"]
insteadOf = [email protected]
[commit]
gpgsign = true
This way, I use the correct email address for both keys and have even set up automatic commit signing for jblige. I also rewrite all the hostnames for the original SSH connections to the correctly suffixed hostnames I created in the SSH config file.
For more information about GPG signing see:
https://help.github.com/en/articles/signing-commits
or
https://confluence.atlassian.com/bitbucketserver/using-gpg-keys-913477014.html
5. Setup Git config includeif
To activate the .gitconfig files in ~/src/*, edit the .gitconfig file in your home directory and add an includeif statement for each of the .gitconfig files referencing the directory they are in
~/.gitconfig
...
[includeif "gitdir:~/src/msmith/"]
path = ~/src/msmith/.gitconfig
[includeif "gitdir:~/src/jblige/"]
path = ~/src/jblige/.gitconfig
Do not forget the trailing slash in the [includeif "gitdir:... statement.
6. Cloning the repositories
You then clone the code using the SSH clone address (i.e. [email protected]... or [email protected]..., not https://bitbucket.org... nor https://github.com...) into the directory that corresponds to the key you want to use for that clone.
$ cd ~/src/msmith
$ git clone [email protected]:someuser/somerepo.git
...
Because of the rewriting, git will actually attempt to clone using the suffixed address corresponding to the configuration in the SSH config file but because of the SSH configuration it will use the original hostname when actually connecting to the host ensuring you use the right key.
All commits/pulls/pushes to/from those repositories will use the corresponding config/key/account.
git pull
kept failing & asking for the school passcode, despite separate Identity files, "IdentitiesOnly=yes," separate domains & Hostnames, all present inssh-add -l
... The uni key was 'first' regardless of that setup. Had to move its section below the others in .ssh/config, and nowgit pull
from both GitHub accts succeeds w/o asking for uni ssh password. – RopysshCommand
git config option. – Penholder