I have set up git config as follows:
Host ACCOUNT1
HostName github.com
Port 22
User git-username1
IdentityFile ~/.ssh/id_rsa_2
Host ACCOUNT2
HostName github.com
Port 22
User git-username2
IdentityFile ~/.ssh/id_rsa
When i git push ACCOUNT1 staging
it fails and says "Permission denied...(PublicKey)"
This is because windows ALWAYS use IdentityFile ~/.ssh/id_rsa
no matter how i rearrange Hosts (ACCOUNTS1 and ACCOUNTS2 above)
UNTIL i rename IdentityFile ~/.ssh/id_rsa_2
to IdentityFile ~/.ssh/id_rsa
, Then git push ACCOUNT1 staging
works....
so every time I have to push to an account I have to make sure its Private Key is named EXACTLY "id_rsa"
Is anyone out there with the solution to ensure git on windows FOLLOW the git config set IdentityFile instead of falling to EXACTLY "id_rsa"?
CodePudding user response:
I have set the remote url as
[email protected]:username/repo
.
Actually, if you want to your your ~/.ssh/config
entries, you need to set the remotes to:
git remote add ACCOUNT1 ACCOUNT1:username/repo
# or, if remote ACCOUNT1 already exists
git remote set-url ACCOUNT1 ACCOUNT1:username/repo
Only then a git push ACCOUNT1 staging
light work.
Without a remote named ACCOUNT1
, git push would use the URL ACCOUNT1
, which is like [email protected]
, with id_rsa_2
, but... without username/repo
.
And pushing to [email protected]
alone will always be "permission denied".
CodePudding user response:
VonC already provided the short answer. Here's the long one.
You're mixing up Git's credentials (used with http / https) and ssh's public / private key based authentication. In particular, this stuff:
Host ACCOUNT1 HostName github.com Port 22 User git-username1 IdentityFile ~/.ssh/id_rsa_2
is a set of instructions for ssh, which you would put in your .ssh/config
file. Git simply runs ssh; ssh then does everything.
These instructions are slightly flawed. In particular you want User git
, not User git-username1
. This allows you to omit git@
in your ssh request. (If you include git@
, the User
line here is ignored, so the flaw becomes unimportant.)
To make ssh use these instructions, you must direct ssh to the pseudo0-host named ACCOUNT1
:
ssh -Tv ACCOUNT1
from the command line, for instance, or ssh -Tv git@ACCOUNT1
. Ssh matches the string literal ACCOUNT1
against the Host
line, and then uses the remaining instructions—HostName
, Port
, User
, and IdentityFile
—when contacting the actual host. The host ssh contacts is that listed in the HostName
section, i.e., github.com
. The port used is 22 (ssh standard, so there's no need to list it). The user name will be git-username1
with the example, which is wrong, so you'd need git@ACCOUNT1
as in the alternative to override the user name.
There's one further line missing: IdentitiesOnly yes
. This is not required but helps cut down on the number of keys your ssh will attempt when it contacts github.com
. With IdentitiesOnly yes
, each key listed in the IdentityFile
line(s)—you can have more than one—will be tried, in the order they are listed. The order can matter since some servers may begin quietly ignoring keys after the first few. (Imagine you're the gatekeeper, watching folks come up and try their keys in the lock at the door to the castle. Someone—you can't see who as the light is too dim—comes up with a huge key ring with 1000 keys on it, and tries them one by one. What do you think about this person?)
So, what I like to do is this:
Host gh1
HostName github.com
User git
IdentitiesOnly yes
IdentityFile ~/.ssh/id_github1
Host gh2
HostName github.com
User git
IdentitiesOnly yes
IdentityFile ~/.ssh/id_github2
and so on. Then, when creating or updating the URL, I use:
git clone ssh://gh1/user/repo.git
or:
git remote set-url origin ssh://gh2/user/repo.git
as appropriate. To test each ssh setting, I use:
ssh -T gh1
or:
ssh -Tvvv gh2
as appropriate. The number of v
s here determines the amount of extra debug output from ssh: stuff at debug level 1 is emitted with one v
, stuff at debug level 2 with 2 v
s, and so on. Debug level 1 suffices to watch the keys being tested.