1913

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?

7
  • 11
    See this question in SuperUser as well. Commented May 8, 2015 at 9:45
  • 83
    I'm wondering why this is so unusual that Git doesn't have an -i option like ssh does. Commented Apr 18, 2016 at 10:55
  • 60
    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 Commented Jul 20, 2016 at 6:48
  • Is it really for one-time use ? If not one should associate host aliases and keys in ~/.ssh/config first. Details here Commented Feb 12, 2021 at 11:02
  • gist.github.com/Tamal/1cc77f88ef3e900aeae65f0e5e504794 here you can find a script with the solution Commented Jul 10, 2021 at 10:31

42 Answers 42

1
2
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 [email protected]: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.

Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

1

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.

Comments

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

Comments

1

for the gitlab RSAAuthentication yes

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

doc is here

1 Comment

doesn't appear to be mentioned on the link you provided any more
1

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

Comments

1

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://[email protected]/userid/test.git

Comments

1

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"

Comments

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 [email protected]: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

1 Comment

it's much easier to just use includeif and a series of config files that set teh sshCommand
0

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'

Comments

0

I feel I have the most elegant solution. The problem for me is caused by having multiple github accounts and not being able to add the same key on multiple accounts.

So create a script somewhere like ~/scripts/gitssh.sh:

#!/bin/bash

ssh -i ~/.ssh/altkey/id_rsa $1 $2

Make it executable chmod +x gitssh.sh

Add a line to .bashrc

alias gitalt="GIT_SSH=~/scripts/gitssh.sh git"

Run a new terminal so it gets loaded and use it like normal git.

gitalt clone [email protected]:yourorganization/reponame.git

Comments

-6

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

1 Comment

NPM package?! This should be a machine-related problem, useless yours is an application-related
1
2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.