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 git@github.com: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 git@github.com: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?
-i
option like ssh
does.
git config core.sshCommand 'ssh -i private_key_file'
. See my answer below
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 git@gitserv:myrepo.git
And then git commands work normally for me.
git push -v origin master
NOTES
The IdentitiesOnly yes is 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_rsa that will get tried BEFORE your ~/.ssh/id_rsa.github without this option.
References
Best way to use multiple SSH private keys on one client
How could I stop ssh offering a wrong key
Something like this should work (suggested by orip):
ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com: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 git@github.com:user/project.git)
Git will invoke SSH which will find its agent by environment variable; this will, in turn, have the key loaded.
Alternatively, setting 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.
ssh-agent bash -c 'ssh-add sshkey; git clone url'
ssh-agent $(..)
syntax isn't working for me and I'm not sure how this is suppose to work: (ba)sh should execute the commands inside $(..)
first, then run ssh-agent with the output as parameter.
Starting from Git 2.3.0 we also have the simple command (no config file needed):
GIT_SSH_COMMAND='ssh -i private_key_file -o IdentitiesOnly=yes' git clone user@host:repo.git
Note the -o IdentitiesOnly=yes
is required to prevent the SSH default behavior of sending the identity file matching the default filename for each protocol as noted in the answer above.
cannot run ssh -i /home/vagrant/.ssh/git: No such file or directory
though it exists 444 Nov 16 18:12 /home/vagrant/.ssh/git
from ls -l /home/vagrant/.ssh/git
chmod 400 <path-to-private-key-file>
. Otherwise git command may fail with no special error message...
-o IdentitiesOnly=yes
to make sure that the key specified with -i
gets used (as opposed to a key from SSH agent).
Other people's suggestions about ~/.ssh/config
are extra complicated. It can be as simple as:
Host github.com
IdentityFile ~/.ssh/github_rsa
IdentitiesOnly
option, too.
git remote add ssh://personal/org/proj.git && git remote add ssh://corporate/org/proj.git
. Then you config looks like Host personal HostName github.com ... Host corporate HostName github.com
IdentitiesOnly
option. Can someone explain why this should be required?
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)
See commit 3c8ede3 (26 Jun 2016) by Nguyễn Thái Ngọc Duy (pclouds
).
(Merged by Junio C Hamano -- gitster
-- in commit dc21164, 19 Jul 2016)
A new configuration variable core.sshCommand has been added to specify what value for GIT_SSH_COMMAND to use per repository.
core.sshCommand:
If this variable is set, git fetch and git push will use the specified command instead of ssh when they need to connect to a remote system. The command is in the same form as the GIT_SSH_COMMAND environment variable and is overridden when the environment variable is set.
It means the git pull
can be:
cd /path/to/my/repo/already/cloned
git config core.sshCommand 'ssh -i private_key_file'
# later on
git pull
You can even set it for just one command like git clone
:
git -c core.sshCommand="ssh -i private_key_file" clone host:repo.git
This is easier than setting a GIT_SSH_COMMAND
environment variable, which, on Windows, as noted by Mátyás Kuti-Kreszács, would be
set "GIT_SSH_COMMAND=ssh -i private_key_file"
git -c core.sshCommand="ssh -i private_key_file" clone host:repo.git
followed by the config set git config core.sshCommand 'ssh -i private_key_file'
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 git@github.com:TheUser/TheProject.git
GIT_SSH="git_wrapper" git clone ssh://user@server/path/to/project"
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 ~/.ssh/config
(or 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 workuser
, run git clone git@github-work:company/project.git
.
IdentitiesOnly yes
to my ssh config file.
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
-F /dev/null
do? As far as I can see this will change configFile from the ~/.ssh/config
default but why is that desired? To ensure a sandboxed command?
The problem is when you have different remote repositories on the same host (say github.com), and you want to interact with them using different ssh keys (i.e. different GitHub accounts).
In order to do that:
First you should declare your different keys in ~/.ssh/config file. # Key for usual repositories on github.com Host github.com HostName github.com User git IdentityFile ~/.ssh/id_rsa # Key for a particular repository on github.com Host XXX HostName github.com User git IdentityFile ~/.ssh/id_other_rsa By doing this you associate the second key with a new friendly name "XXX" for github.com. Then you must change the remote origin of your particular repository, so that it uses the friendly name you've just defined. Go to your local repository folder within a command prompt, and display the current remote origin: >git remote -v origin git@github.com:myuser/myrepo.git (fetch) origin git@github.com:myuser/myrepo.git (push) Then change origin with: >git remote set-url origin git@XXX:myuser/myrepo.git >git remote -v origin git@XXX:myuser/myrepo.git (fetch) origin git@XXX:myuser/myrepo.git (push) Now you can push, fetch... with the right key automatically.
git
command I get: ssh: Could not resolve hostname helloworld-wp-github: Name or service not known fatal: Could not read from remote repository.
User git
was what I was missing. You can test connection with ssh -vT XXX
( docs.github.com/en/authentication/troubleshooting-ssh/… )
The fastest and simplest way of doing it is by:
Clone your repo with ssh:
git -c core.sshCommand="ssh -i ~/.ssh/<your_key>" clone git@github.com:<user>/<repo>.git
then cd
into you cloned repo and:
git config core.sshCommand 'ssh -i ~/.ssh/<your_key>'
To test it's working:
git --git-dir=/path/to/repo/.git pull
So you may wonder: why my created ssh key does not work after I planted the .pub in github and the private is in the default directory?
The documentation gives us a command that clarifies the issue: ssh -vT git@github.com
The output shows a list of ssh keys names git looks for. So, you may want to create your key with one of those names, or use the above process to include the one you need.
git clone -c "core.sshCommand=ssh -i ~/.ssh/<your_key>" git@github.com:<user>/<repo>.git
. Notice the -c
option comes after clone
, not before.
GIT_SSH_COMMAND="ssh -i /path/to/git-private-access-key" git clone $git_repo
or
export GIT_SSH_COMMAND="ssh -i /path/to/git-private-access-key"
git clone REPO
git push
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)
git clone git@gh-work:repo/project.git
In my ~/.ssh/config I have two sections that both use github.com for HostName. They just have different IdentityFile and Host
~/.ssh/config
pastebin.com/8rYn7yCi
From Git version 2.10.0, you can configure this per repo or globally
git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -o 'IdentitiesOnly yes'"
This will specify for the current repo what ssh key will use. I assume if you want to specify this global only need to set the --global
option.
fatal: not in a git directory
.
\
including the C:\Users
path but had to alter it verbatim as you had it with the standard Unix path syntax ~/
. This worked perfectly for my and especially helpful with the note about setting the --global
option which was all but implied for most cases
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.
File ~/gitwrap.sh
#!/bin/bash
ssh -i ~/.ssh/gitkey_rsa "$@"
Then, in my .bashrc, add the following:
export GIT_SSH=~/gitwrap.sh
gitwrap.sh
, for example /home/ubuntu/gitwrap.sh
-o StrictHostKeyChecking=no
to the ssh command
2021. If you're on a Mac.
Say you have an ubuntu server on aws, which you normally connect to like this:
% ssh -i blah/yourkeypair.pem ubuntu@test.fattie.com
In terminal just
% export GIT_SSH_COMMAND="ssh -i /Users/fattie/Desktop/blah/yourkeypair.pem"
After you have done that. You can then freely ...
% git clone ubuntu@test.fattie.com:/home/ubuntu/teste.git
That will clone the repo on your server to your local folder "teste",
you can then freely when in teste/ do the usual commands such as ...
% git push origin master
and so on.
--
Note also: https://stackoverflow.com/a/67287133/294884
As for on the server, it seems you basically
] git clone --bare the-actual-folder teste.git
and then in teste.git
] git init --bare --shared
If none of the other solutions here work for you, and you have created multiple ssh-keys, but still cannot do simple things like
git pull
then assuming you have two ssh key files like
id_rsa
id_rsa_other_key
then inside of the git repo, try:
# Run these commands INSIDE your git directory
eval `ssh-agent -s`
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_rsa_other_key
and also make sure your github default username and userid are correct by:
# Run these commands INSIDE your git directory
git config user.name "Mona Lisa"
git config user.email "mona.lisa@email.com"
See https://gist.github.com/jexchan/2351996 for more more information.
Could not open a connection to your authentication agent.
, try $ eval `ssh-agent -s`
, and try again.
ssh-add
command trick worked for me. Add's the identity key to the list of those which are tried when ssh authenticates. This worked for me well!
ssh-add
?
.git
inside the repo not the git program globally. You can use --global
to set global username and email.
When you need to connect to github with a normal request (git pull origin master
), setting the Host as *
in ~/.ssh/config
worked for me, any other Host (say, "github" or "gb") wasn't working.
Host *
User git
Hostname github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_xxx
Host my-host-alias
, you have to set remote.origin.url=git@my-host-alias:[username]/[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:
How to Specify an ssh Key File with the git
command
The point being that there is no git
command such as the following:
git -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/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 thatuser@myserver.com:/git/repo.git
Where git.sh
is:
#!/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 \$@" > /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 "$@"
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 (e.g. system("bash git.sh -i ~/.ssh/thatuserkey.pem pull")
).
Not that R is the same as Ruby, but if R can do it... O:-)
GIT_SSH_COMMAND="ssh -i ~/.ssh/thatuserkey.pem" git clone clone thatuser@myserver.com:/git/repo.git
as per Robert Jack Will's answer?
A lot of good answers, but some of them assume prior administration knowledge.
I think it is important to explicitly emphasize that if you started your project by cloning the web URL - https://github.com/<user-name>/<project-name>.git
then you need to make sure that the url
value under [remote "origin"]
in the .git/config
was changed to the SSH URL (see code block below).
With addition to that make sure that you add the sshCommmand
as mentioned below:
user@workstation:~/workspace/project-name/.git$ cat config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
sshCommand = ssh -i ~/location-of/.ssh/private_key -F /dev/null <--Check that this command exist
[remote "origin"]
url = git@github.com:<user-name>/<project-name>.git <-- Make sure its the SSH URL and not the WEB URL
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
Read more about it here.
I just needed to add the key then run the git clone again.
ssh-add ~/.ssh/id_rsa_mynewkey
git clone git@bitbucket.org:mycompany/myrepo.git
if you have directory on your path where you want to sign with a given identifyfile you can specify to use a specific identify file via the .ssh/config file by setting the ControlPath
e.g.:
host github.com
ControlPath ~/Projects/work/**
HostName github.com
IdentityFile ~/.ssh/id_work
User git
Then ssh
will use the specified identity file when doing git commands under the given work path.
ControlMaster auto
and ControlPersist yes
, so that you do not need to retype the password every time. Found the info in this article
In Windows with Git Bash you can use the following to add a repository
ssh-agent bash -c 'ssh-add "key-address"; git remote add origin "rep-address"'
for example:
ssh-agent bash -c 'ssh-add /d/test/PrivateKey.ppk; git remote add origin git@git.test.com:test/test.git'
Which private key is in drive D, folder test of computer. Also if you want to clone a repository, you can change git remote add origin
with git clone
.
After enter this to Git Bash, it will ask you for passphrase!
Be Aware that openssh private key and putty private key are different!
If you have created your keys with puttygen, you must convert your private key to openssh!
The problem with this method is, at least when running by bash.exe on Windows, that it will create a new process every time which will remain dormant.
ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git'
If you want want to use that for syncig repo on schedule then you need to add "&& ssh-agent -k" at the end.
Something like:
ssh-agent bash -c 'ssh-add C:/Users/user/.ssh/your_key; git -C "C:\Path\to\your\repo" pull && ssh-agent -k'
ssh-agent -k will kill the process when it's done.
Most of the answers given here do not explain the details for the most basic usage.
After you have setup a server (in this case a linux
server) in the cloud, you connect to it using ssh from the terminal.
From your computer, add the private key dyson-ubuntu-vm.pem
which is given to you by your cloud services provider such as Azure, AWS etc to your .ssh configuration on your local machine like this:
Copy the .pem
file to the /home/ssenyonjo/.ssh
folder, then open /home/ssenyonjo/.ssh/config
file and add the following entry:
Host 20.85.213.44
HostName 20.85.213.44
User Dyson
IdentityFile /home/ssenyonjo/.ssh/dyson-ubuntu-vm.pem
IdentitiesOnly yes
Now from your terminal, access the cloud linux server like so:
ssh Dyson@20.85.213.44
When that works, create a git project on the cloud server like so:
Dyson@dyson-ubuntu-vm:~/projects$ git init --bare s2
Now come back to your local machine and clone that empty repository like so:
ssenyonjo@ssenyonjo-pc:~/Projects/mastering-git$ git clone ssh://Dyson@20.85.213.44/home/Dyson/projects/s2
If you see an error that looks something like: fatal: Could not read from remote repository
, It means you're accessing the wrong folder. Ensure you have outlined the right path from the root to the created repository.
If you dont want to setup a config file but want to access the ssh server that requires a key, you can use below command:
GIT_SSH_COMMAND='ssh -i ~/Projects/aws/keys/aws_ubuntu.pem' git clone ssh://ubuntu@15.207.99.158/home/ubuntu/projects/mastering-git/rand
You can export the command to continue using it for other tasks like git push
and git pull
export GIT_SSH_COMMAND='ssh -i ~/Projects/aws/keys/aws_ubuntu.pem'
See: https://stackoverflow.com/a/29754018/10030693
To have GIT_SSH_COMMAND environment variable work under Windows(CMD) instead of:
set GIT_SSH_COMMAND="ssh -i private_key_file"
Use:
set "GIT_SSH_COMMAND=ssh -i private_key_file"
The quote has to be like
set "variable=value"
Some backgorund: https://stackoverflow.com/a/34402887/10671021
You need to create a ~/.ssh/config as below
Host <Your bitbucket server>
User <userid>
Hostname <Your bitbucket server as above>
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa<file> This is your private key file
permission as below
-rw------- $HOME/.ssh/config
Add your public key into your git (cat ~/.ssh/id_rsa_pub [or simillar name])
and then git clone as below
git clone ssh://blahblah@blah.com/userid/test.git
This is an extension to @VonC's answer. Please read it first.
Use case is I need to use both personal and work GitHub accounts using SSH. I want to use work SSH key as default as my projects will internally have other work repos as dependency. So cloning them should work seamlessly.
Steps I followed are:
Generate default SSH key and add it to work git account.
Generate personal SSH key in a separate file and add it to personal git account.
Add the following function code in your .bashrc or .zshrc file and source it. gclone() { # Clone the repo-url using personal ssh-key git -c core.sshCommand="ssh -i path_to_personal_key" clone "$1" && # Extract repo name from URL using "awk" and switch to that folder using "cd" cd $(awk '{ sub(/.*\//, ""); sub(/\.git.*/, ""); print }' <<< "$1") && # Set personal ssh-key as default for this repo git config core.sshCommand "ssh -i path_to_personal_key"; }
Use gclone command to clone repos using personal SSH key and set the repo to use that key as default.
Use normal git clone command to clone repos with default(work) SSH key.
This command clones the repo and configures the SSH key to use permanently:
git clone -c "core.sshCommand=ssh -i ~/.ssh/<key>" git@github.com:<user>/<repo>.git
Now, if you run git fetch
, git pull
, or git push
, it will use the SSH key configured in core.sshCommand
(saved in .git/config
).
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.
I use zsh
and different keys are loaded to my zsh shell's ssh-agent
automatically for other purposes (i.e. access to remote servers) on my laptop. I modified @Nick's answer and I'm using it for one of my repos that needs to be refreshed often. (In this case it's my dotfiles
which I want same and latest version across my all machines, wherever I'm working.)
bash -c 'eval `ssh-agent`; ssh-add /home/myname/.dotfiles/gitread; ssh-add -L; cd /home/myname/.dotfiles && git pull; kill $SSH_AGENT_PID'
Spawn an ssh-agent
Add read-only key to agent
Change directory to my git repo
If cd to repo dir is successful, pull from remote repo
Kill spawned ssh-agent. (I wouldn't want many of agents lingering around.)
Success story sharing
Host remote.server.com
and keep using the original URLchmod 600 ~/.ssh/config
(see here). And if you are using GitHub, replaceHost gitserv
withHost github.com
, omitHostname remote.server.com
, and add remote withgit remote add origin git@github.com:user_name/repo_name.git
.