Git clone with custom SSH using GIT_SSH error
Asked Answered
F

6

60

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?

Featherston answered 8/1, 2013 at 17:41 Comment(3)
What happens if you just run /usr/bin/ssh -o StrictHostKeyChecking=no -i /home/me/my_private_key in your prompt?Lacroix
it show me usage info because I haven't supplied username and host. If I supply, I just get denied (which was expected)Featherston
Git 2.3+ (Q1 2015) will allow a more complete ssh command definition (with the new environment variable GIT_SSH_COMMAND). See my answer belowFalstaffian
M
105

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.

Moonlight answered 8/1, 2013 at 17:47 Comment(0)
F
35

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

Falstaffian answered 22/12, 2014 at 17:44 Comment(0)
E
8

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.

Escolar answered 1/1, 2018 at 13:36 Comment(1)
Nice workaround, for those environments with old Git. +1Falstaffian
A
7

Use ssh-agent

ssh-agent bash -c 'ssh-add /home/me/my_private_key; git clone [email protected]:uname/test-git-repo.git'
Acquittance answered 12/5, 2014 at 6:52 Comment(1)
ssh_askpass is also invoked for host key verification.Northumbria
E
5

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.

Eventful answered 24/3, 2013 at 10:12 Comment(1)
This answer is confusing and contortedly useless because one should first follow that link and create the script/s contained therein. And those also seem contorted, given that (as other have shown) there are ways to do what the OP wanted with simple, git-standard environment variables or SSH config files.Eyehole
E
0

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

Edla answered 6/1, 2023 at 18:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.