Specify an SSH key for git push for a given domain
Solution 1
Even if the user and host are the same, they can still be distinguished in ~/.ssh/config
. For example, if your configuration looks like this:
Host gitolite-as-alice
HostName git.company.com
User git
IdentityFile /home/whoever/.ssh/id_rsa.alice
IdentitiesOnly yes
Host gitolite-as-bob
HostName git.company.com
User git
IdentityFile /home/whoever/.ssh/id_dsa.bob
IdentitiesOnly yes
Then you just use gitolite-as-alice
and gitolite-as-bob
instead of the hostname in your URL:
git remote add alice git@gitolite-as-alice:whatever.git
git remote add bob git@gitolite-as-bob:whatever.git
Note
You want to include the option IdentitiesOnly yes
to prevent the use of default ids. Otherwise, if you also have id files matching the default names, they will get tried first because unlike other config options (which abide by "first in wins") the IdentityFile
option appends to the list of identities to try. See: https://serverfault.com/questions/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807
Solution 2
You can utilize git environment variable GIT_SSH_COMMAND
. Run this in your terminal under your git repository:
GIT_SSH_COMMAND='ssh -i ~/.ssh/your_private_key' git submodule update --init
Replace ~/.ssh/your_private_key
with the path of ssh private key you wanna use. And you can change the subsequent git command (in the example is git submodule update --init
) to others like git pull
, git fetch
, etc.
Solution 3
An alternative approach to the one offered above by Mark Longair is to use an alias that will run any git command, on any remote, with an alternative SSH key. The idea is basically to switch your SSH identity when running the git commands.
Advantages relative to the host alias approach in the other answer:
- Will work with any git commands or aliases, even if you can't specify the
remote
explicitly. - Easier to work with many repositories because you only need to set it up once per client machine, not once per repository on each client machine.
I use a few small scripts and a git alias admin
. That way I can do, for example:
git admin push
To push to the default remote using the alternative ("admin") SSH key. Again, you could use any command (not just push
) with this alias. You could even do git admin clone ...
to clone a repository that you would only have access to using your "admin" key.
Step 1: Create the alternative SSH keys, optionally set a passphrase in case you're doing this on someone else's machine.
Step 2: Create a script called “ssh-as.sh” that runs stuff that uses SSH, but uses a given SSH key rather than the default:
#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"
Step 3: Create a script called “git-as.sh” that runs git commands using the given SSH key.
#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"
Step 4: Add an alias (using something appropriate for “PATH_TO_SCRIPTS_DIR” below):
# Run git commands as the SSH identity provided by the keyfile ~/.ssh/admin
git config --global alias.admin \!"PATH_TO_SCRIPTS_DIR/git-as.sh ~/.ssh/admin"
More details at: http://noamlewis.wordpress.com/2013/01/24/git-admin-an-alias-for-running-git-commands-as-a-privileged-ssh-identity/
Solution 4
Configure your repository using git config
git config --add --local core.sshCommand 'ssh -i <<<PATH_TO_SSH_KEY>>>'
This applies to your local repository only.
Solution 5
I've cribbed together and tested with github the following approach, based on reading other answers, which combines a few techniques:
- correct SSH config
- git URL re-writing
The advantage of this approach is, once set up, it doesn't require any additional work to get it right - for example, you don't need to change remote URLs or remember to clone things differently - the URL rewriting makes it all work.
~/.ssh/config
# Personal GitHub
Host github.com
HostName github.com
User git
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/github_id_rsa
# Work GitHub
Host github-work
HostName github.com
User git
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/work_github_id_rsa
Host *
IdentitiesOnly yes
~/.gitconfig
[user]
name = My Name
email = [email protected]
[includeIf "gitdir:~/dev/work/"]
path = ~/dev/work/.gitconfig
[url "github-work:work-github-org/"]
insteadOf = [email protected]:work-github-org/
~/dev/work/.gitconfig
[user]
email = [email protected]
As long as you keep all your work repos under ~/dev/work and personal stuff elsewhere, git will use the correct SSH key when doing pulls/clones/pushes to the server, and it will also attach the correct email address to all of your commits.
References:
user1678401
Software engineer working on a model based testing tool. Experienced in Ruby, Java, Python, AWK and associated technologies. Dabbles in Clojure, Haskell, Racket and C.
Updated on July 10, 2022Comments
-
user1678401 almost 2 years
I have the following use case: I would like to be able to push to
[email protected]:gitolite-admin
using the private key of usergitolite-admin
, while I want to push to[email protected]:some_repo
using 'my own' private key. AFAIK, I can't solve this using~/.ssh/config
, because the user name and server name are identical in both cases. As I mostly use my own private key, I have that defined in~/.ssh/config
for[email protected]
. Does anyone know of a way to override the key that is used for a singlegit
invocation?(Aside: gitolite distinguishes who is doing the pushing based on the key, so it's not a problem, in terms of access, ownership and auditing, that the user@server string is identical for different users.)