1730

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?

Yuri
  • 4,254
  • 1
  • 29
  • 46
Christoffer
  • 25,035
  • 18
  • 53
  • 77
  • 10
    See [this question in SuperUser](http://superuser.com/q/232373/90668) as well. – Flimm May 08 '15 at 09:45
  • 71
    I'm wondering why this is so unusual that Git doesn't have an `-i` option like `ssh` does. – Nick T Apr 18 '16 at 10:55
  • 55
    With git 2.10 (Q3 2016), you also have a new config: `git config core.sshCommand 'ssh -i private_key_file'`. See [my answer below](http://stackoverflow.com/a/38474137/6309) – VonC Jul 20 '16 at 06:48
  • 4
    In my opinion, the HeyWatchThis answer should be the accepted answer as it allows for all git commands to be executed as normal after the setup rather than having to make a subshell for each git command as the current accepted answer requires. – gloriphobia Aug 23 '17 at 15:20
  • Is it really for one-time use ? If not one should associate host aliases and keys in ~/.ssh/config first. [Details here](https://stackoverflow.com/a/56067132/2637795) – rodzmkii Feb 12 '21 at 11:02
  • https://gist.github.com/Tamal/1cc77f88ef3e900aeae65f0e5e504794 here you can find a script with the solution – open-ecommerce.org Jul 10 '21 at 10:31
  • This is documented already: https://git-scm.com/docs/gitfaq#Documentation/gitfaq.txt-HowdoIusemultipleaccountswiththesamehostingproviderusingSSH – crimson_king Sep 21 '21 at 23:27
  • Hey, since September 2016 when git version 2.10 was released, the best answer is the one provided by VonC. Simple and straightforward solution, both for global scope and for each command. Take a look down below be happy! http://stackoverflow.com/a/38474137/6309 – MMJ Sep 02 '22 at 12:26
  • 1
    The `core.sshCommand` solution by @VonC is the only solution that works after a reboot. – Andrew Koster Feb 15 '23 at 23:32
  • I had to purge everything from my ssh agent before it would work because for some reason it kept picking up the old one no matter what. A reboot may also fix this I guess. – Wes May 30 '23 at 14:05

40 Answers40

1610

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

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
HeyWatchThis
  • 21,241
  • 6
  • 33
  • 41
  • 32
    I found that when you specify multiple keys using .ssh/config, you need to use host friend name in line "Host" as part of "git remote add" command. If line is "Host stg", then you need to use git remote add user@stg:/path_to_git_repo.git ". If you use exact server name like user@myserver.com:/path_to_git_repo.git, the config file is not picked by git. Hence, it is not picking private key file correctly. I tried this by pushing same content to github and heroku and works only when you give friendly name in "git remote add" – Gopinath M.R Jul 15 '13 at 23:46
  • 3
    I wasn't sure about the Host for github. I found this link: https://gist.github.com/jexchan/2351996. – Karsten Jul 15 '14 at 09:40
  • @JonnyReeves edits introduced mismatched hostnames. Pushing to `gitserv` will not match the ssh config `Host` entry for `remote` or `remote.server.com`. Therefore the intended `IdentityFile` will not be used. I'm going to edit this answer. – Bruno Bronosky Jul 29 '14 at 16:29
  • 1
    Take a look [here](http://nerderati.com/2011/03/17/simplify-your-life-with-an-ssh-config-file/) if you want to have few key files for few git repositories – e271p314 Sep 09 '14 at 14:37
  • Hope the SSH config solution could support get account name from this format `git@github.com:/some_repo.git that you don't have to modify the host for different account names when do the clone. – Enze Chi Mar 30 '15 at 23:08
  • I don't understand why `IdentitiesOnly` is necessary. As I understand it, by adding this host to the config file, it will add this ssh key to a list of keys that it will try, i.e. it will first try `~/.ssh/identity`, `~/.ssh/id_dsa`, `~/.ssh/id_ecdsa` and `~/.ssh/id_rsa` and then it will try `~/.ssh/id_rsa.github`. Is there anything wrong with it trying `id_rsa` before `id_rsa.github`, as long as it eventually tries `id_rsa.github`? – sid-kap Aug 31 '15 at 14:40
  • Umm this doesn't work for me. When I do a git pull from my private repo, git ignores my `.ssh/config` file completely and tries id_rsa instead, which is the wrong key. – starbeamrainbowlabs Apr 25 '16 at 09:55
  • I had all of this except for `IdentitiesOnly` and it worked for a while but then one day stopped working and was trying to use my default key in `id_rsa`. `IdentifiesOnly` does seem to be important. – Stefan Avey May 22 '16 at 19:51
  • 4
    You could use `Host remote.server.com` and keep using the original URL – MauganRa Aug 09 '16 at 13:03
  • For some reason, this worked for me, but I add to SSH-login to the Git server first for the identifyFile to be used (Probably has to do with the known_hosts not being populated). So, after doing that, and before running your `git clone ...` command, run: `ssh {hostname}` – Guillaume S. Dec 27 '16 at 10:19
  • Also User may be required in the config entry – Roman Susi May 21 '18 at 05:24
  • 27
    This worked for me after two changes. If the config file is new, don't forget to do `chmod 600 ~/.ssh/config` (see [here](https://superuser.com/questions/232373/how-to-tell-git-which-private-key-to-use)). And if you are using GitHub, replace `Host gitserv` with `Host github.com`, omit `Hostname remote.server.com`, and add remote with `git remote add origin git@github.com:user_name/repo_name.git`. – miguelmorin Jun 21 '18 at 11:30
  • 1
    `IdentitiesOnly yes` did it! I was going mad. I tried to setup GitLab with a custom SSH key - this should be part of the official documentation. – Kevin G. Oct 13 '18 at 16:57
  • 1
    This is exactly what I was after. Completely forgot about ~/.ssh/config. Thank you kind stranger. – Ed Neville Nov 09 '18 at 21:25
  • 1
    Is it possible same host but different subfolders ? ie "Host bitbucket.org" but different keys for different projects – Ignacio Vazquez Nov 26 '18 at 14:30
  • The fact to add a new remote did the trick for me. For the context : I add a new key during a project and wanting to push with it. – Paul Leclerc Dec 18 '18 at 10:24
  • 1
    To save some more characters, add `User git` into that configuration item and just use `gitserv:myrepo.git` as remote URL. – iBug Mar 28 '19 at 16:10
  • This is the only answer that also works with Windows if you are using the ssh client that comes with Git (located at `%ProgramFiles%\Git\usr\bin\ssh.exe` by default). Modify or create the `config` file located at `%USERPROFILE%\.ssh\config`. – cowlinator Apr 09 '20 at 19:37
  • I needed to use `Host` instead of `Hostname`. I.e. `Host xfce.org\nHost gitlab.xfce.org` – DarkTrick Jul 07 '20 at 13:28
  • github: HostName github.com User git (answered by Karsten), gitlab: HostName gitlab.com User git – mirek Jan 06 '21 at 12:11
  • it looks like the comment makes it fail: /root/.ssh/config line 4: garbage at end of line; "#". so if this is the case, remove the comment – Felipe Valdes Apr 12 '22 at 12:55
1111

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.

Nick T
  • 25,754
  • 12
  • 83
  • 121
Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
  • 12
    But this will add the key permanently as an accepted SSH-key, right? I want to avoid that so that theuser2 can't mess with theuser's projects. It's for a web application so it's not practical to use different OS-users, which would have been the best option. – Christoffer Dec 30 '10 at 19:55
  • 43
    No, when git completes, ssh-agent terminates, and the key is forgotten. – Martin v. Löwis Dec 30 '10 at 19:56
  • 7
    this command does'not work on windows git bash. It says syntax error near unexpected token 'ssh-add' – Mohit Sep 19 '11 at 19:02
  • 121
    Fixed command line (for windows or linux) would be something like: `ssh-agent bash -c 'ssh-add sshkey; git clone url'` – orip Nov 10 '11 at 00:00
  • This works fine on my desktop *nix machines, but fails on several servers that are virgin installs of current Debian. @HeyWatchThis's answer seems to work everywhere (although it's permanent where this one is temporary) – Adam May 05 '13 at 20:18
  • bash crashes on windows for me (using git bash environment variables). Is there a workaround for windows. – Sohaib Dec 11 '14 at 13:47
  • I've fixed the syntax of the first command line: it should be `$( ... )` to launch a subshell. – kynan Oct 28 '15 at 16:48
  • 8
    The `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. – Johannes 'fish' Ziemke Dec 28 '15 at 11:55
  • 2
    How will this solution work if the key has a passphrase? – Starx Aug 31 '16 at 04:48
  • Thanks a lot, this works for me. My OS X is pretty wired that I can only use the ssh-agent way you mentioned to access the git server, directly using git clone will get ```Permission denied (publickey,gssapi-keyex,gssapi-with-mic). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.``` even the private key is just in ~/.ssh/id_rsa and ssh-add -l has showed it correctly. Do you have any idea about this? – cyl19910101 Oct 05 '16 at 11:15
  • Unfortunately instead of removing the key, it left it there. You should add a ssh-add -d /path/to/key at the end. – Jistanidiot Sep 21 '17 at 18:54
  • 7
    The `$(..)` syntax probably doesn't do what you expect: it runs the commands inside first and sends their output to `ssh-agent`. This might happen to work anyway if another `ssh-agent` happens to be already running, but then the new key will be left in the agent (unless you add `ssh-add -d` to take it out) and the answer becomes `ssh-add /somewhere/yourkey && git clone git@github.com:user/project.git ; ssh-add -d /somewhere/yourkey` (and we assume `ssh-agent` is already running, and note the use of `&&` rather than `;`). But that's moot because the `bash -c` version is correct. – Silas S. Brown Mar 07 '18 at 11:20
  • 1
    This solution stopped working for me for some reason after I upgraded from OpenSUSE 42.3 to 15.0. I switched to https://stackoverflow.com/a/29754018/47680, which is working well. – Artem Russakovskii Dec 28 '18 at 18:16
  • 4
    You also accomplish this with `ssh-add -t 60; git clone git@github.com:user/project.git`. That will just expire the key after 60 seconds. – Jacktose Jan 08 '19 at 19:45
  • This worked for me on Windows 10 for quite some time, but in the past week it's stopped working and I can't seem to pinpoint the change. Infact it fails to work on two separate systems. The ssh-agent service despite running, reports nothing though running with `-d` generates a `cannot create agent root reg key, ERROR:5` error. – Robin May 25 '21 at 06:14
  • And then do `git config core.sshCommand "ssh -i /path/to/key"` so that it remembers your key every time you do a git fetch / git pull – 101010 Jul 29 '21 at 14:54
  • this answer should be replaced with ones suggesting `git config core.sshCommand` – nurettin Apr 17 '22 at 20:37
  • Chef's kiss for this approach – Yash Jakhotiya Sep 30 '22 at 19:26
854

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.

Hamish Downer
  • 16,603
  • 16
  • 90
  • 84
Robert Jack Will
  • 10,333
  • 1
  • 21
  • 29
  • 3
    I get `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` – ted Nov 16 '15 at 18:28
  • 3
    @ted: chmod 400 /home/vagrant/.ssh/git – Yash Feb 15 '16 at 12:43
  • 10
    Nice and easy solution. I suggest creating an alias if you need to do this a lot. – Lasse Meyer Jul 25 '16 at 10:55
  • @ted Read [What permissions levels should I give to the private key?](http://stackoverflow.com/q/9270734) if confused. – Franklin Yu Aug 14 '16 at 16:28
  • Perfect solution and works without any issues in cygwin – Pierre Aug 30 '16 at 16:46
  • Great solution for managing multiple repositories, especially if you have them on the same account with different keys. – Optimae Oct 08 '17 at 02:53
  • 10
    Don't forget to `chmod 400 `. Otherwise git command may fail with no special error message... – eonil Dec 10 '17 at 14:48
  • This is the best solution, consider you want to pull the code later, GIT_SSH_COMMAND='ssh -i private_key_file' git pull origin branch_name Its simple and it works. – shijin Nov 29 '18 at 13:49
  • 1
    This worked for me using Git 2.13.6 on Mac. I was able to clone a remote repo over a SSH forward proxy. Thanks! Note: I only had to `export GIT_SSH_COMMAND='ssh -i private_key_file'` though. – hmacias Dec 06 '18 at 17:04
  • Please note that also .ssh folder has to be granted permissions, besides the subfolder as mentioned above... so be sure to run `chmod 400 path/to/.ssh` too... – Emi-C Nov 22 '19 at 11:56
  • 9
    It would be good if this answer also included `-o IdentitiesOnly=yes` to make sure that the key specified with `-i` gets used (as opposed to a key from SSH agent). – robinst Jan 06 '20 at 03:23
  • To do this from within PowerShell: `$env:GIT_SSH_COMMAND='ssh -i private_key_file -o IdentitiesOnly=yes'; git clone user@host:repo.git` – Robin May 25 '21 at 10:45
  • Yea alias is nice, ```alias GIT="GIT_SSH_COMMAND='ssh -i private_key_file -o IdentitiesOnly=yes' git"```, and then e.g. ```GIT push``` – dermen Dec 02 '21 at 19:23
  • If you have identities specified in your `~/.ssh/config` file that you want to ignore, you will also need to add `-F /dev/null` to the `ssh` command. – wheeler May 25 '22 at 15:27
  • For those looking for a per repo config, you can add this to the `core.sshCommand` config option for your repo. Note that the path to the identity file should resolve from the repo as your directory, so typically it should be something like `~/.ssh/identity_file`. – suvayu Jun 26 '23 at 07:23
  • If you're on Windows WSL you might need a sudo if permissions are too open, so like this: `sudo GIT_SSH_COMMAND='ssh -i /mnt/c/Users/dome/path/to/mykey -o IdentitiesOnly=yes' git push git@github.com:do-me/SemanticFinder.git`. – do-me Jul 10 '23 at 20:50
524

Other people's suggestions about ~/.ssh/config are extra complicated. It can be as simple as:

Host github.com
  IdentityFile ~/.ssh/github_rsa
philfreo
  • 41,941
  • 26
  • 128
  • 141
  • 38
    You need the `IdentitiesOnly` option, too. – Flimm Jul 03 '15 at 14:56
  • 7
    @EnzeChi you can have multiple github accounts by manipulating the remotes: `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` – emory May 04 '17 at 11:52
  • @EnzeChi I do something similar so that I use 2 different ssh keys - one for fetching and the other for pushing. The fetch does not have a passphrase. The push does. – emory May 04 '17 at 11:53
  • 10
    Mine works without the `IdentitiesOnly` option. Can someone explain why this should be required? – AlbinoDrought Aug 18 '20 at 04:16
  • 1
    Not exactly fitting granularity. My company has an organisation on github and I have a personal account on github, so with just the host it does not work nicely. – anydoby Jan 04 '22 at 13:11
  • 1
    Is there a difference between `Host *.github.com` and `Host github.com`? – theonlygusti Nov 18 '22 at 19:22
  • @anydoby you can make custom hosts: `Host mypersonalgithub // HostName github.com // IdentityFIle personalgithub_ed25519` and `Host companygithub // HostName github.com // IdentityFIle company_ed25519` – theonlygusti Nov 18 '22 at 19:25
  • @AlbinoDrought it likely works because the host doesn't care how many keys you try. Some hosts reject the connection after a certain number of failed keys. – Doktor J Nov 18 '22 at 19:32
  • @theonlygusti I have not had issues with *.github.com until today after months of it working fine. I did add more entries in my config file but should have been unrelated. After removing the `*.` it started working immediately – Richard Tyler Miles Sep 03 '23 at 04:13
352

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"

For all those commands, you can add a -o IdentitiesOnly=yes to limit SSH to the the private/public key you are specifying:

git config core.sshCommand 'ssh -i private_key_file -o IdentitiesOnly=yes' 
# or
git -c core.sshCommand="ssh -i private_key_file -o IdentitiesOnly=yes" clone host:repo.git
# or
set "GIT_SSH_COMMAND=ssh -i private_key_file -o IdentitiesOnly=yes"

gsullins suggests in the comments to adds to the .zshrc the following alias:

alias git.key1="git config core.sshCommand 'ssh -i <absolute path to private key>'"
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • @Flimm release dates: https://calendar.google.com/calendar/embed?src=jfgbl2mrlipp4pb6ieih0qr3so@group.calendar.google.com&pli=1 – VonC Aug 04 '16 at 11:03
  • It has been released. – Flimm Nov 10 '16 at 10:13
  • @Flimm yes: that is what my revision (http://stackoverflow.com/posts/38474137/revisions) mentions. – VonC Nov 10 '16 at 10:16
  • Yeah, but the comments haven't been deleted. I've deleted my old comment and flagged the other comments as "obsolete". – Flimm Nov 10 '16 at 10:20
  • 15
    Works. Folks should consider this the best answer. Once issued, it can be informative to diff the .git/config file with a version copied to /tmp beforehand. A new entry has been created: sshCommand = ... For what it's worth, I used 'git config core.sshCommand "ssh -i $HOME/.ssh/privatekeyfile". – WeakPointer Mar 08 '18 at 23:02
  • 1
    Only works with an existing git directory. Otherwise you need to set it globally which isn't really what you want. – Spanky Dec 06 '18 at 19:49
  • 9
    @Spanky You can do the inline command `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' ` – dav_i Jan 09 '20 at 16:33
  • 6
    This is definitely the best answer! – Wagner Patriota Mar 01 '20 at 04:38
  • Spanky's right that the snippet following the _"It means the git clone can be:"_ is incorrect. `git config` doesn't work outside of a git working directory. – Nickolay Aug 17 '20 at 01:18
  • Thanks for mentioning version as well. I was wondering why it's not working on the CentOS server that I'm running it on and it was version 1.8.3.1. – coladict Jul 02 '21 at 14:06
  • @coladict Good point. I have seen 1.8.3.1 too many time, even in 2021 (and 1.8.3.1 was released in... June 2013 (https://github.com/git/git/releases/tag/v1.8.3.1) – VonC Jul 02 '21 at 14:23
  • 3
    This is great. Automatically set the key per repository. – daviewales Apr 08 '22 at 00:09
  • 1
    This works great thank you. Had to workaround another issue on Windows, if you are using the native Windows ssh and the Windows ssh-agent service you will need to specify the path to the windows ssh otherwise it will use the ssh shipped with git and you'll have to type the password in every time. ```git config core.sshCommand 'C:/Windows/System32/OpenSSH/ssh.exe -i C:/Users/firstname.lastname/.ssh/mygitkey_ed25519 -o IdentitiesOnly=yes' ``` – holytshirt Apr 20 '22 at 15:12
  • @holytshirt True. I always set the PATH to reference the ssh I want (`C:\Program Files\Git\usr\bin\ssh.exe` in my case). That way, no full path to specify. – VonC Apr 20 '22 at 17:24
  • I like this answer, as well. i've added `alias git.key1="git config core.sshCommand 'ssh -i '"` to my .zshrc file for easy replication. – gsullins Dec 21 '22 at 22:56
  • @gsullins Thank you for the feedback, nice alias. I have included your comment in the answer for more visibility. – VonC Dec 21 '22 at 23:24
  • Agreed - should be accepted answer. Also, does the SSH command need `-o IdentitiesOnly=yes`? – Johntron Jan 25 '23 at 06:18
  • @Johntron The `-o IdentitiesOnly=yes` is not *mandatory* but can help limit SSH to use only the specified private key instead of falling back to other possible authentication mechnism. – VonC Jan 25 '23 at 09:17
164

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
Joe Block
  • 1,872
  • 1
  • 12
  • 11
  • 5
    Very good solution if you have more than one account at the same domain, which other solutions don't handle well – Beka Apr 26 '14 at 08:54
  • 1
    Nice solution. You can also simplify this with > GIT_SSH=my_git_ssh_wrapper; git clone git@github.com:TheUser/TheProject.git – Shiva May 06 '14 at 23:40
  • 2
    This solution also covers situations when you want to use git from account without home directory. – piotrekkr May 19 '14 at 08:14
  • Fantastic. You can use this way to private servers too: `GIT_SSH="git_wrapper" git clone ssh://user@server/path/to/project"` – ton Apr 10 '15 at 22:41
  • 1
    This is the only way that worked for me in a cygwin environment – ChatterOne Jun 22 '16 at 12:37
  • 1
    Don't forget to add executable permissions to script to avoid "Permission denied" error – Panoptik Oct 19 '20 at 14:48
  • After cloning with this wrapper, you can set the wrapping command inside this particular project's git config `cd projectname ; git config core.sshCommand 'ssh -i private_key_file -o IdentitiesOnly=yes' `, and then you wont need to use wrapper for subsequent pulls – rilian Jul 10 '23 at 15:03
158

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.

Antony Hatchkins
  • 31,947
  • 10
  • 111
  • 111
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
  • 4
    I downvoted you because everything you say is already covered in the answers above, and in my eyes, even more clearly. For instance, why exactly do you define the User to e dandv and workuser, respectively? – hroptatyr Mar 27 '15 at 12:34
  • 3
    You answered a 4 year old question with no new informations and you are claiming that your answer is "the best way". Moreover you downvoted and hassled other users to remove their answer ... just to get your one pushed up. – rudimeier Mar 27 '15 at 13:03
  • @hroptatyr: I've used `dandv` and `workuser` to support my example, "e.g. a personal GitHub account and a work one". `dandv` is my GitHub username. – Dan Dascalescu Mar 28 '15 at 07:50
  • 1
    You've actually got the right idea here, but this won't work. You have to use user 'git'. The problem is, you're duplicating thamster's reply from 2012. – jthill May 08 '15 at 15:39
  • 14
    I think it's a better answer than @thamster's, if only because it explains host aliases. – David Moles Apr 18 '16 at 17:12
  • 3
    I like this answer. However, for me this only works if I add `IdentitiesOnly yes` to my ssh config file. – winni2k Feb 17 '17 at 11:14
  • the problem with any solution that has you creating duplicate host entries with different aliases are two: 1. you need to remember them 2. some tooling will infer the http web interface of the remote from the ssh remote, this breaks it. – airtonix Feb 25 '22 at 03:38
107

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:

  1. 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.

  2. 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.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
rodzmkii
  • 1,357
  • 1
  • 10
  • 7
  • 3
    This is the most "right" answer in my mind, where you organize connections and keys in your ssh config file that is best practice and supportable long term. – james-see Jun 18 '19 at 13:13
  • Other solutions seem like workarounds, this is using great feature the tool supports. – Craig.C Nov 20 '19 at 11:05
  • 1
    This sounds like exactly what I'm looking for, but I can't get it working. Whenever I run a `git` command I get: `ssh: Could not resolve hostname helloworld-wp-github: Name or service not known fatal: Could not read from remote repository.` – maskedjellybean Feb 15 '21 at 23:21
  • Did you add a new entry in your ~/.ssh/config ? This is how you tell ssh that your "helloworld-wp-github" is an alias for "github.com". Then, and only then, you can use your alias as remote server in git commands. – rodzmkii Feb 16 '21 at 15:20
  • Done Same but it is not working, as hostname is same for personal and Company – Abhishek Thapliyal Jun 23 '21 at 08:56
  • 1
    Adding `User git` was what I was missing. You can test connection with `ssh -vT XXX` ( https://docs.github.com/en/authentication/troubleshooting-ssh/error-permission-denied-publickey ) – arsenik Nov 25 '21 at 13:31
  • this is a horrible answer to be honest. you now have to remember all these special domain names and any tooling that relies on the git remote being correctly transferrable to a http web interface is now broken. what's that somerandomproject.github.com doesn't exist? oh no? dramalama! The correct solution is to use the core.sshCommand, bonus points if you persist it with your ~/.dotfiles/.gitconfig and make use of includeif logic – airtonix Feb 25 '22 at 03:29
  • Despite this comment being really clear, it took me a long time to nail this but I finally got it! The key is `Host` alias. Commenting so I can find the damn thing next... I dunno, week probably. – Soft Bullets May 04 '22 at 07:58
  • I only really got here by accident - and then I was quite puzzled as to why apparently everybody was just assuming that the OP had multiple GitHub accounts. Because if you don't, then a simply entry in your `~/.ssh/config` as shown above will do. – Martin Baulig Apr 22 '23 at 00:16
99

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
Community
  • 1
  • 1
David
  • 2,741
  • 16
  • 26
  • 1
    What does `-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? – Dominic Mar 23 '17 at 12:26
  • 4
    http://linuxcommand.org/man_pages/ssh1.html, specifies no config file, so when git will run ssh, no config file will be passed (in fact it's a kind of sandbox mode, just ignore user config default options) Original thread in superuser has more info about -F – David Mar 23 '17 at 16:04
  • 1
    The one I was looking for. Thanks! – lostcitizen Mar 04 '19 at 18:35
  • AAAAA+ solution for working in kuber environment. Thanks! – Cobra vs Ninja Apr 10 '19 at 08:49
  • 1
    Hi Do you know how to propagate this to a submodule? – Arka Prava Basu Dec 27 '19 at 13:34
  • How can I put this is bash_profile as alias? Always getting errors. – z.a. Jan 27 '20 at 04:58
  • Why would you put this in your `.bash_profile` as an alias? You just run it once (for each repo). In general, use functions instead of aliases and your life will be easier; but both are slightly hard if you are confused about quoting. – tripleee Mar 04 '20 at 19:57
  • git -c core.sshCommand="ssh -i ~/.ssh/{key}" clone {repo} – Rudresh Narwal Feb 26 '23 at 09:24
65

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.

RicHincapie
  • 3,275
  • 1
  • 18
  • 30
  • To add to this, you should be configuring this by using another feature of gitconfig: includeif. – airtonix Feb 25 '22 at 03:24
  • You can replace the two commands with this one command: `git clone -c "core.sshCommand=ssh -i ~/.ssh/" git@github.com:/.git` . Notice the `-c` option comes after `clone`, not before. – Flimm Jun 24 '22 at 14:00
  • `-i` is merely a suggestion without further flags. To avoid this heresy, expand it to `ssh -o IdentitiesOnly=yes -o IdentityFile=~/.ssh/ --identity_file=~/.ssh/`. – airtonix Oct 04 '22 at 22:56
48
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
Leo Ufimtsev
  • 6,240
  • 5
  • 40
  • 48
carlsborg
  • 2,628
  • 19
  • 21
  • That is clean. I want to add `GIT_SSH_COMMAND="ssh -i /path/to/git-private-access-key" git clone repo` if anyone want to use it temporarily. – Rafik Farhad Oct 17 '22 at 18:05
41

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)
jackslash
  • 8,550
  • 45
  • 56
thamster
  • 1,542
  • 1
  • 11
  • 10
  • 1
    That's useful, but makes you use the repo key for all interaction with that hostname. If there are other repos on the same server that require different keys, using a wrapper and telling git to use it with GIT_SSH is better. – Joe Block Jan 03 '13 at 22:27
  • 11
    That's not necessarily true. I use multiple keys for Github - one for work and one for my personal account. You don't have to put a domain name for "Host". You can put any kind of alias you want. For example, I use gh-home and gh-work as my hostnames and when I clone I use, for example, `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 – blockloop Dec 18 '13 at 17:35
  • @brettof86 this strategy works for the most part, but what do you do when a repository you are checking out depends on a gem which is also hosted on github? The the reference to the github repo in the Gemfile wont contain your "alias", well not unless you want to break things for other developers on the project... – ktec Mar 28 '15 at 16:58
  • @brettof86 I also have two different github accounts (work, home), but I cannot get the example to work for me. Can you post a sample of having two? – Climbs_lika_Spyder Jun 04 '15 at 18:43
  • @Climbs_lika_Spyder here's what's in my `~/.ssh/config` http://pastebin.com/8rYn7yCi – blockloop Jun 05 '15 at 19:50
  • @brettof86 it says this paste has been removed :( – Climbs_lika_Spyder Jun 08 '15 at 15:20
  • @Climbs_lika_Spyder the gist is missing now too -___- – qodeninja Jul 29 '15 at 23:38
  • I can paste it here, but it's going to be ugly... `Host work-gh HostName github.com PreferredAuthentications publickey IdentityFile ~/.ssh/work_id_rsa Host github.com HostName github.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa` – blockloop Aug 06 '15 at 22:40
  • The gist is here https://gist.github.com/justbrettjones/5f9940effeba9f36daa6#file-gistfile1-txt – blockloop Aug 06 '15 at 22:41
  • Your answer so helpeful that I signed in just to give thumps up!! This was really useful – Student of Science Jun 12 '20 at 20:53
41

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.

MrPompeii
  • 561
  • 5
  • 6
  • 1
    How do I specify this for checkout? I mean, I've just created a new empty folder, opened console, went inside this folder and executed this command. It tells me: `fatal: not in a git directory`. – izogfif Mar 26 '21 at 12:27
  • 2
    You need to initialize git, with git init – MrPompeii Mar 28 '21 at 02:17
  • Using __WSL2__ I had originally set the path using standard forward-slashes ``\`` 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 – tijko Mar 09 '22 at 00:42
33

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
Fábio Batista
  • 25,002
  • 3
  • 56
  • 68
Jamie
  • 1,888
  • 1
  • 18
  • 21
  • I did set this on .bashrc. But when I login to openshift instance, it does not seems to be calling it. Am I missing something ? – Jigar Shah Feb 11 '13 at 06:48
  • It fails with an error for me.. its not able to find the script event though its there.. not sure whats going on...error: cannot run /tmp/gitwrap.sh: No such file or directory – ap1234 Jul 26 '16 at 00:24
  • If you face "No such file or directory" error, put full path of `gitwrap.sh`, for example `/home/ubuntu/gitwrap.sh` – Tahir Akhtar Oct 27 '17 at 13:15
  • you might want to add `-o StrictHostKeyChecking=no` to the ssh command – dan-man Feb 21 '19 at 12:53
  • I tried to implement this, but I was not happy with the fact that I needed an extra script file to act as a wrapper, and when I checked the documentation, I found an easier way. You can use `GIT_SSH_COMMAND` to specify the command you want git to use. In my case (different private key), I had to do this: `export GIT_SSH_COMMAND="ssh -i ~/.ssh/my_alternative_private_key"` and then continue to use git as normal in the script. – Luxian Mar 07 '23 at 22:50
30

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).

Flimm
  • 136,138
  • 45
  • 251
  • 267
19

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.

cgnorthcutt
  • 3,890
  • 34
  • 41
  • 2
    Note if you get `Could not open a connection to your authentication agent.`, try `$ eval \`ssh-agent -s\``, and try again. – cgnorthcutt Feb 14 '19 at 23:09
  • 1
    For those who are lost, the `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! – Ben Cartwright Feb 26 '19 at 01:34
  • Why do you think it matters in which directory you run `ssh-add`? – tripleee Mar 04 '20 at 19:59
  • @BenCartwright Because you are modifying local settings, not global settings. This approach modifies `.git` inside the repo not the git program globally. You can use `--global` to set global username and email. – cgnorthcutt Mar 05 '20 at 20:52
  • this seems to me like a more accurate solution for the problem. Thanks. It Worked – gzcarlosrd Aug 24 '23 at 17:47
19

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
Fattie
  • 27,874
  • 70
  • 431
  • 719
15

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
Rafael Corrêa Gomes
  • 1,751
  • 1
  • 22
  • 31
  • it's simple and work for me. I have had multi account in Github and got stuck to know to add multi keys. Thank you so much. – Nam Nguyen Feb 09 '23 at 15:00
  • This worked for me[,](https://semicolon.dev/stackoverflow/question/16/how-can-i-designate-a-specific-private-ssh-key-for-git-shell-commands) thanks. – InfiniteStack Aug 05 '23 at 17:14
14

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:-)

Paul 'Joey' McMurdie
  • 7,295
  • 5
  • 37
  • 41
  • 1
    Looks like great! I will test this and reply back. – Muneer May 27 '15 at 05:31
  • 3
    Apart from the syntax, how is this better than `GIT_SSH_COMMAND="ssh -i ~/.ssh/thatuserkey.pem" git clone clone thatuser@myserver.com:/git/repo.git` as per [Robert Jack Will's answer](http://stackoverflow.com/a/29754018/27358)? – David Moles Apr 18 '16 at 17:18
13

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
chopstik
  • 363
  • 2
  • 10
  • Might as well leave the entire "Host *" line out then. – lionello Jun 26 '14 at 04:22
  • 1
    It probably wasn't working because it didn't match your remote URL. If you want to use `Host my-host-alias`, you have to set `remote.origin.url=git@my-host-alias:[username]/[repo].git`. – David Moles Apr 18 '16 at 17:15
13

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.

Rot-man
  • 18,045
  • 12
  • 118
  • 124
  • 2
    Thank you so much, spent so much time trying to figure out why git is not using ssh key. I don't understand why github gives https url as default in clone button. – Chakradar Raju May 12 '20 at 05:37
  • 1
    Solid answer, provides info for project level config instead of system wide config. Other answers seem to ignore that you basically only run into this problem if you don't have a system wide configuration! – Malcolm Jul 22 '20 at 19:00
9

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.

cristobal
  • 462
  • 5
  • 14
  • Found out later that you can also set the properties `ControlMaster auto` and `ControlPersist yes`, so that you do not need to retype the password every time. Found the info in this [article](https://developer.rackspace.com/blog/speeding-up-ssh-session-creation/) – cristobal May 03 '19 at 06:41
  • ControlPath Specify the path to the control socket used for connection sharing as described in the ControlMaster section above or the string ''none'' to disable connection sharing. In the path, '%l' will be substituted by the local host name, '%h' will be substituted by the target host name, '%p' the port, and '%r' by the remote login username. It is recommended that any ControlPath used for opportunistic connection sharing include at least %h, %p, and %r. This ensures that shared connections are uniquely identified. – George L. Yermulnik Sep 03 '21 at 09:00
  • actually this sounds like an unintentional side effect of the proper use of ControlPath – airtonix Feb 25 '22 at 03:32
7

Why don't you just add location of identity key to git config file for a particular repo like this:

cd .git

vi config

[core]
    sshCommand = ssh -i <IDENTITY_KEY_LOCATION> -o IdentitiesOnly=yes

That's all you need.

Hannes
  • 420
  • 4
  • 8
  • Is this in the repo? How do you then clone it in the first place? How does it work when others clone it, or I use a different machine? – crobar Mar 16 '23 at 11:51
  • `GIT_SSH_COMMAND="ssh -i -o IdentitiesOnly=yes" git clone …` and then this answer. – Hannes Apr 21 '23 at 22:40
5

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!

Peyman Mahdavi
  • 179
  • 2
  • 7
5

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

Gilbert
  • 2,699
  • 28
  • 29
4

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

4

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.

Mike Z.
  • 109
  • 3
3

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.

codeVerine
  • 742
  • 3
  • 14
3

Clone in one command

git -c core.sshCommand='ssh -i /path/to/key/' clone git@github.com:your_repository.git /path/target/clone --branch git_branch_name
Hix.botay
  • 387
  • 3
  • 10
2

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
1

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.)
1

for the gitlab RSAAuthentication yes

Host gitlab.com
  RSAAuthentication yes
  IdentityFile ~/.ssh/your_private_key_name
  IdentitiesOnly yes

doc is here

Alupotha
  • 9,710
  • 4
  • 47
  • 48
1

Also, as a simple "workaround", if you don't really need it that often:

Remove all ssh identities from the currently running ssh agent (not physically).

ssh-add -D

Re-add the one you need to work with to your currently running ssh-agent

ssh-add ~/.ssh/MyProperProfile

Do the gits

Optionally - revert by adding other identities (or all of 'em).

Der Zinger
  • 506
  • 7
  • 13
  • NOTE: The command will delete all your keys!!! @Der Zinger Please Note this in your post with a Bold text! – Amin.Qarabaqi Feb 01 '23 at 04:44
  • I don't really get what this "warning" should be about sir. This command (`ssh-add -D`) quote: `Removes all identities from the agent.`. It does not `delete` anything from anywhere. The actual keys are still physically there, exactly where they where before that command, and can be easily re-added with the next command I've listed. The only thing this command do - makes sure that `ssh-agent` (and everything that relies on it, like `git`) does not "know" about your keys. – Der Zinger Feb 07 '23 at 06:50
1

Don't overcomplicate things, just use ssh-add to add a temporary identity

alias gpullpersonal='ssh-add mykey;git pull;ssh-add -D'
alias gpullprofessional='ssh-add myotherkey;git pull;ssh-add -D'
lalo
  • 901
  • 2
  • 10
  • 15
0

If SSH port number is not 22(default), add Port xx in ~/.ssh/config

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
w..k
  • 60
  • 4
0

If you're like me, you can:

  • Keep your ssh keys organized

  • Keep your git clone commands simple

  • Handle any number of keys for any number of repositories.

  • Reduce your ssh key maintenance.

I keep my keys in my ~/.ssh/keys directory.

I prefer convention over configuration.

I think code is law; the simpler it is, the better.

STEP 1 - Create Alias

Add this alias to your shell: alias git-clone='GIT_SSH=ssh_wrapper git clone'

STEP 2 - Create Script

Add this ssh_wrapper script to your PATH:

#!/bin/bash
# Filename: ssh_wrapper

if [ -z ${SSH_KEY} ]; then
    SSH_KEY='github.com/l3x'  # <= Default key
fi
SSH_KEY="~/.ssh/keys/${SSH_KEY}/id_rsa"
ssh -i "${SSH_KEY}" "$@"

EXAMPLES

Use github.com/l3x key:

KEY=github.com/l3x git-clone https://github.com/l3x/learn-fp-go

The following example also uses the github.com/l3x key (by default):

git-clone https://github.com/l3x/learn-fp-go

Use bitbucket.org/lsheehan key:

KEY=bitbucket.org/lsheehan git-clone git@bitbucket.org:dave_andersen/exchange.git

NOTES

Change the default SSH_KEY in the ssh_wrapper script to what you use most of the time. That way, you don't need to use the KEY variable most of the time.

You may think, "Hey! That's a lot going on with an alias, a script and some directory of keys," but for me it's convention. Nearly all my workstations (and servers for that matter) are configured similarly.

My goal here is to simplify the commands that I execute regularly.

My conventions, e.g., Bash scripts, aliases, etc., create a consistent environment and helps me keep things simple.

KISS and names matter.

For more design tips check out Chapter 4 SOLID Design in Go from my book: https://www.amazon.com/Learning-Functional-Programming-Lex-Sheehan-ebook/dp/B0725B8MYW

Hope that helps. - Lex

l3x
  • 30,760
  • 1
  • 55
  • 36
0

I was able to resolve this requirement with following command option to git clone --config core.sshCommand="ssh -i /d/repos/ssh/prod-a/.ssh/id_ed25519"

0

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.

sam-w
  • 7,478
  • 1
  • 47
  • 77
rudimeier
  • 854
  • 1
  • 8
  • 20
-2

Here's the ssh key hack i found while finding solution to this problem:

For example you have 2 different set of keys:

key1, key1.pub, key2, key2.pub

Keep these keys in your .ssh directory

Now in your .bashrc or .bash_profile alias file, add these commands

alias key1='cp ~/.ssh/key1 id_rsa && cp ~/.ssh/key1.pub id_rsa.pub'

alias key2='cp ~/.ssh/key2 id_rsa && cp ~/.ssh/key2.pub id_rsa.pub'

Voila! You have a shortcut to switch keys whenever you want!

Hope this works for you.

penduDev
  • 4,743
  • 35
  • 37
  • Please add information about how to use these keys using git – Sergey Nemchinov Aug 10 '20 at 08:54
  • @SergeyNemchinov you just have to run `key1` or `key2` on the terminal and respective key pairs become the default keys for your system.. then you don't need to explicitly specify which key you want to use with git. It use the default key. – penduDev Aug 20 '20 at 05:50
-5

You can try sshmulti npm package for maintaining multiple ssh key.

Anto Khan
  • 39
  • 1
  • 4