git - with - Specify private SSH-key to use when executing shell command?
use private key git clone (12)
As stated here: https://superuser.com/a/912281/607049
You can configure it per-repo:
git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null" git pull git push
A rather unusual situation perhaps, but I want to specify a private SSH-key to use when executing a shell (git) command from the local computer.
Basically like this:
git clone [email protected]:TheUser/TheProject.git -key "/home/christoffer/ssh_keys/theuser"
Or even better (in Ruby):
with_key("/home/christoffer/ssh_keys/theuser") do sh("git clone [email protected]:TheUser/TheProject.git") end
I have seen examples of connecting to a remote server with Net::SSH that uses a specified private key, but this is a local command. Is it possible?
Contents of my_git_ssh_wrapper:
#!/bin/bash ssh -i /path/to/ssh/secret/key $1 $2
Then you can use the key by doing:
GIT_SSH=my_git_ssh_wrapper git clone [email protected]:TheUser/TheProject.git
I went with the GIT_SSH environment variable. Here's my wrapper, similar to that from Joe Block from above, but handles any amount of arguments.
#!/bin/bash ssh -i ~/.ssh/gitkey_rsa "[email protected]"
Then, in my .bashrc, add the following:
If SSH port number is not 22(default), add
Port xx in
In my case (synology),
Host my_synology Hostname xxxx.synology.me IdentityFile ~/.ssh/id_rsa_xxxx User myname Port xx
Then clone using Host title in config. ("my_synology". to avoid @chopstik 's "*")
git clone my_synology:path/to/repo.git
Many of these solutions looked enticing. However, I found the generic git-wrapping-script approach at the following link to be the most useful:
The point being that there is no
git command such as the following:
git -i ~/.ssh/thatuserkey.pem clone [email protected]:/git/repo.git
Alvin's solution is to use a well-defined bash-wrapper script that fills this gap:
git.sh -i ~/.ssh/thatuserkey.pem clone [email protected]:/git/repo.git
#!/bin/bash # The MIT License (MIT) # Copyright (c) 2013 Alvin Abad # https://alvinabad.wordpress.com/2013/03/23/how-to-specify-an-ssh-key-file-with-the-git-command if [ $# -eq 0 ]; then echo "Git wrapper script that can specify an ssh-key file Usage: git.sh -i ssh-key-file git-command " exit 1 fi # remove temporary file on exit trap 'rm -f /tmp/.git_ssh.$$' 0 if [ "$1" = "-i" ]; then SSH_KEY=$2; shift; shift echo "ssh -i $SSH_KEY \[email protected]" > /tmp/.git_ssh.$$ chmod +x /tmp/.git_ssh.$$ export GIT_SSH=/tmp/.git_ssh.$$ fi # in case the git command is repeated [ "$1" = "git" ] && shift # Run the git command git "[email protected]"
I can verify that this solved a problem I was having with user/key recognition for a remote bitbucket repo with
git remote update,
git pull, and
git clone; all of which now work fine in a
cron job script that was otherwise having trouble navigating the limited-shell. I was also able to call this script from within R and still solve the exact same
cron execute problem
system("bash git.sh -i ~/.ssh/thatuserkey.pem pull")).
Not that R is the same as Ruby, but if R can do it... O:-)
None of these solutions worked for me.
Instead, I elaborate on @Martin v. Löwis 's mention of setting a
config file for SSH.
SSH will look for the user's
~/.ssh/config file. I have mine setup as:
Host gitserv Hostname remote.server.com IdentityFile ~/.ssh/id_rsa.github IdentitiesOnly yes # see NOTES below
And I add a remote git repository:
git remote add origin [email protected]:myrepo.git
And then git commands work normally for me.
git push -v origin master
IdentitiesOnly yesis required to prevent the SSH default behavior of sending the identity file matching the default filename for each protocol. If you have a file named
~/.ssh/id_rsathat will get tried BEFORE your
~/.ssh/id_rsa.githubwithout this option.
Something like this should work (suggested by orip):
ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone [email protected]:user/project.git'
if you prefer subshells, you could try the following (though it is more fragile):
ssh-agent $(ssh-add /somewhere/yourkey; git clone [email protected]:user/project.git)
Git will invoke SSH which will find its agent by environment variable; this will, in turn, have the key loaded.
HOME may also do the trick, provided you are willing to setup a directory that contains only a
.ssh directory as
HOME; this may either contain an identity.pub, or a config file setting IdentityFile.
Starting from Git 2.3.0 we also have the simple command (no config file needed):
GIT_SSH_COMMAND='ssh -i private_key_file' git clone [email protected]:repo.git
You may need a restart for the ssh service on your machine.
To sum up answers and comments, the best way to set up git to use different key files and then forget about it, which also supports different users for the same host (e.g. a personal GitHub account and a work one), which works on Windows as well, is to edit
c:\Users\<your user>\.ssh\config) and specify multiple identities:
Host github.com HostName github.com IdentityFile /path/to/your/personal/github/private/key User dandv Host github-work HostName github.com IdentityFile /path/to/your/work/github/private/key User workuser
Then, to clone a project as your personal user, just run the regular
git clone command.
To clone the repo as the
git clone [email protected]:company/project.git.
Way better idea to add that host or ip to the
.ssh/config file like so:
Host (a space separated list of made up aliases you want to use for the host) User git Hostname (ip or hostname of git server) PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa_(the key you want for this repo)
With git 2.10+ (Q3 2016: released Sept. 2d, 2016), you have the possibility to set a config for
GIT_SSH_COMMAND (and not just an environment variable as described in Rober Jack Will's answer)
A new configuration variable
core.sshCommandhas been added to specify what value for GIT_SSH_COMMAND to use per repository.
If this variable is set,
git pushwill use the specified command instead of
sshwhen they need to connect to a remote system.
The command is in the same form as the
GIT_SSH_COMMANDenvironment variable and is overridden when the environment variable is set.
It means the
git clone can be:
cd /path/to/my/repo git config core.sshCommand 'ssh -i private_key_file' # later on git clone host:repo.git
You could use GIT_SSH environment variable. But you will need to wrap ssh and options into a shell script.
See git manual:
man git in your command shell.