Paris
Paris

Reputation: 6761

Git clone with custom SSH using GIT_SSH error

I am trying to clone a Git repo using a custom SSH command. I set the SSH command in the GIT_SSH environmental variably be running

export GIT_SSH="/usr/bin/ssh -o StrictHostKeyChecking=no -i /home/me/my_private_key".

But when, after the previous command I run

git clone [email protected]:uname/test-git-repo.git, I get the following weird error

error: cannot run /usr/bin/ssh -o StrictHostKeyChecking=no -i /home/me/my_private_key
fatal: unable to fork

Can you please help me out solve this issue?

Upvotes: 61

Views: 79979

Answers (6)

uanr81
uanr81

Reputation: 409

Personally, I use the SSH configuration file for this purpose. You can specify in it all that is required. The manual says "git fetch and git push will use the specified command instead of ssh" but with "git clone" and others works well. Example of a part of the ssh.conf file:

Host khnSrv_al
HostName 192.168.1.201
Port 22
User al
LogLevel ERROR
PasswordAuthentication no
StrictHostKeyChecking no
IdentityFile /ubData/docs/PktDstSSH/key
UserKnownHostsFile /dev/null

Example of launch:

al@rznCad:~$ GIT_SSH_COMMAND="ssh -F /ubData/docs/PktDstSSH/config" git clone khnSrv_al:~/DrktrRepo/GNU_Gdb_10.1
Клонирование в «GNU_Gdb_10.1»…
remote: Перечисление объектов: 275, готово.
remote: Подсчет объектов: 100% (275/275), готово.
remote: Сжатие объектов: 100% (160/160), готово.
remote: Всего 275 (изменений 114), повторно использовано 275 (изменений 114), повторно использовано пакетов 0
Получение объектов: 100% (275/275), 1.51 МиБ | 10.44 МиБ/с, готово.
Определение изменений: 100% (114/114), готово.

The line "-F /ubData/docs/PktDstSSH/config" specifies the path to the ssh client configuration file, the line "khnSrv_al:~/DrktrRepo/GNU_Gdb_10.1" the path to the repository directory for cloning, "khnSrv_al:" the hostname as specified in the configuration file. With this approach, you can use repository access control using SSH certificates and your own CA.

al@rznCad:~$ git -C ~/GNU_Gdb_10.1 remote -v
origin  khnSrv_al:~/DrktrRepo/GNU_Gdb_10.1 (fetch)
origin  khnSrv_al:~/DrktrRepo/GNU_Gdb_10.1 (push)

#fetch
al@rznCad:~$ GIT_SSH_COMMAND="ssh -F /ubData/docs/PktDstSSH/config" git -C ~/GNU_Gdb_10.1 fetch origin master
Из khnSrv_al:~/DrktrRepo/GNU_Gdb_10.1
 * branch            master     -> FETCH_HEAD

#push
al@rznCad:~$ GIT_SSH_COMMAND="ssh -F /ubData/docs/PktDstSSH/config" git -C ~/GNU_Gdb_10.1 push origin master
Everything up-to-date

"-C ~/GNU_Gdb_10.1" Local repository directory

Upvotes: 0

Chen Levy
Chen Levy

Reputation: 16338

Building on larsk's answer and VonC's answer, you can create a git_ssh.sh script such as:

#!/bin/sh
# Workaround: GIT_SSH_COMMAND isn't supported by Git < 2.3
exec ${GIT_SSH_COMMAND:-ssh} "$@"

Then invoke your git command like this:

export GIT_SSH_COMMAND="/usr/bin/ssh -o StrictHostKeyChecking=no -i /home/me/my_private_key"
export GIT_SSH=path/to/git_ssh.sh
git ...

This is how it works:

In Git v2.3+ $GIT_SSH_COMMAND takes precedence over $GIT_SSH, but older versions don't respect $GIT_SSH_COMMAND at all.

$GIT_SSH can hold only a path to the ssh command on the system. It can't pass extra command line arguments to that command, so how can we pass extra arguments to ssh?

A workaround is to create a script that includes the ssh command and its extra arguments. This is exactly what the git_ssh.sh is all about: Since we already set $GIT_SSH_COMMAND to be /usr/bin/ssh -o StrictHostKeyChecking=no -i /home/me/my_private_key, it is exactly what we need to exec, and the "$@" is here to pass the arguments passed to git_ssh.sh by Git itself to the $GIT_SSH_COMMAND.

The ${...:-ssh} part, while not strictly needed is a nice touch that will make $GIT_SSH_COMMAND default to the ssh command, and thus setting GIT_SSH=git_ssh.sh will not break a normal git execution.

As added value, this script is totally ignored by Git v2.3+, and the $GIT_SSH_COMMAND is used directly in this case.

Upvotes: 8

VonC
VonC

Reputation: 1323753

Note that starting with git 2.3+ (Q1 2015), what you initially tried would work, with the new environment variable GIT_SSH_COMMAND.

See commit 3994276 from Thomas Quinot (quinot):

git_connect: set ssh shell command in GIT_SSH_COMMAND

It may be impractical to install a wrapper script for GIT_SSH when additional parameters need to be passed.
Provide an alternative way of specifying a shell command to be run, including command line arguments, by means of the GIT_SSH_COMMAND environment variable, which behaves like GIT_SSH but is passed to the shell.

The special circuitry to modify parameters in the case of using PuTTY's plink/tortoiseplink is activated only when using GIT_SSH; in the case of using GIT_SSH_COMMAND, it is deliberately left up to the user to make any required parameters adaptation before calling the underlying ssh implementation.

GIT_SSH_COMMAND:

If either of these environment variables is set then 'git fetch' and 'git push' will use the specified command instead of 'ssh' when they need to connect to a remote system.
The command will be given exactly two or four arguments:

  • the 'username@host' (or just 'host') from the URL and the shell command to execute on that remote system, optionally preceded by '-p' (literally) and
  • the 'port' from the URL when it specifies something other than the default SSH port.

$GIT_SSH_COMMAND takes precedence over $GIT_SSH, and is interpreted by the shell, which allows additional arguments to be included.
$GIT_SSH on the other hand must be just the path to a program (which can be a wrapper shell script, if additional arguments are needed).

Upvotes: 36

TlmaK0
TlmaK0

Reputation: 3886

Use ssh-agent

ssh-agent bash -c 'ssh-add /home/me/my_private_key; git clone [email protected]:uname/test-git-repo.git'

Upvotes: 7

larsks
larsks

Reputation: 311486

You cannot provide options in the GIT_SSH environment variable; from the git man page:

   GIT_SSH
       If this environment variable is set then git fetch and git push will use this command instead of ssh when they need to connect
       to a remote system. The $GIT_SSH command will be given exactly two arguments: the username@host (or just host) from the URL
       and the shell command to execute on that remote system.

       To pass options to the program that you want to list in GIT_SSH you will need to wrap the program and options into a shell
       script, then set GIT_SSH to refer to the shell script.

One option is to add a stanza to your .ssh/config file with the appropriate configuration:

Host bitbucket.org
  StrictHostKeyChecking no
  IdentityFile /home/me/my_private_key

Another option is to point GIT_SSH to a shell script that does what you want. E.g., in /home/me/bin/bitbucket_ssh, put:

#!/bin/sh
exec /usr/bin/ssh -o StrictHostKeyChecking=no -i /home/me/my_private_key "$@"

And then point GIT_SSH at /home/me/bin/bitbucket_ssh.

I prefer using .ssh/config when possible, because this avoids the need to create a per-destination script for each remote.

Upvotes: 106

alvinabad
alvinabad

Reputation: 5096

You can supply any keyfile you wish to use with the Git command like this:

$ PKEY=~/.ssh/keyfile.pem git clone [email protected]:me/repo.git

or this:

$ git.sh -i ~/.ssh/keyfile.pem clone [email protected]:me/repo.git

I answered the same question here: https://stackoverflow.com/a/15596980

See link for details.

Upvotes: 5

Related Questions