mirror of
https://github.com/git/git.git
synced 2026-01-26 18:44:50 +00:00
Merge pull request #1006 from segevfiner/git-ssh-command-putty
connect: recognize [tortoise]plink in GIT_SSH_COMMAND
This commit is contained in:
@@ -1981,6 +1981,17 @@ Environment variable settings always override any matches. The URLs that are
|
||||
matched against are those given directly to Git commands. This means any URLs
|
||||
visited as a result of a redirection do not participate in matching.
|
||||
|
||||
ssh.variant::
|
||||
Depending on the value of the environment variables `GIT_SSH` or
|
||||
`GIT_SSH_COMMAND`, or the config setting `core.sshCommand`, Git
|
||||
auto-detects whether to adjust its command-line parameters for use
|
||||
with plink or tortoiseplink, as opposed to the default (OpenSSH).
|
||||
+
|
||||
The config variable `ssh.variant` can be set to override this auto-detection;
|
||||
valid values are `ssh`, `plink`, `putty` or `tortoiseplink`. Any other value
|
||||
will be treated as normal ssh. This setting can be overridden via the
|
||||
environment variable `GIT_SSH_VARIANT`.
|
||||
|
||||
i18n.commitEncoding::
|
||||
Character encoding the commit messages are stored in; Git itself
|
||||
does not care per se, but this information is necessary e.g. when
|
||||
|
||||
@@ -1027,6 +1027,12 @@ Usually it is easier to configure any desired options through your
|
||||
personal `.ssh/config` file. Please consult your ssh documentation
|
||||
for further details.
|
||||
|
||||
`GIT_SSH_VARIANT`::
|
||||
If this environment variable is set, it overrides Git's autodetection
|
||||
whether `GIT_SSH`/`GIT_SSH_COMMAND`/`core.sshCommand` refer to OpenSSH,
|
||||
plink or tortoiseplink. This variable overrides the config setting
|
||||
`ssh.variant` that serves the same purpose.
|
||||
|
||||
`GIT_ASKPASS`::
|
||||
If this environment variable is set, then Git commands which need to
|
||||
acquire passwords or passphrases (e.g. for HTTP or IMAP authentication)
|
||||
|
||||
75
connect.c
75
connect.c
@@ -691,6 +691,49 @@ static const char *get_ssh_command(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int handle_ssh_variant(const char *ssh_command, int is_cmdline,
|
||||
int *port_option, int *needs_batch)
|
||||
{
|
||||
const char *variant = getenv("GIT_SSH_VARIANT");
|
||||
char *p = NULL;
|
||||
|
||||
if (variant)
|
||||
; /* okay, fall through */
|
||||
else if (!git_config_get_string("ssh.variant", &p))
|
||||
variant = p;
|
||||
else if (!is_cmdline) {
|
||||
p = xstrdup(ssh_command);
|
||||
variant = basename(p);
|
||||
} else {
|
||||
const char **ssh_argv;
|
||||
|
||||
p = xstrdup(ssh_command);
|
||||
if (split_cmdline(p, &ssh_argv)) {
|
||||
variant = basename((char *)ssh_argv[0]);
|
||||
/*
|
||||
* At this point, variant points into the buffer
|
||||
* referenced by p, hence we do not need ssh_argv
|
||||
* any longer.
|
||||
*/
|
||||
free(ssh_argv);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcasecmp(variant, "plink") ||
|
||||
!strcasecmp(variant, "plink.exe") ||
|
||||
!strcasecmp(variant, "putty"))
|
||||
*port_option = 'P';
|
||||
else if (!strcasecmp(variant, "tortoiseplink") ||
|
||||
!strcasecmp(variant, "tortoiseplink.exe")) {
|
||||
*port_option = 'P';
|
||||
*needs_batch = 1;
|
||||
}
|
||||
free(p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This returns a dummy child_process if the transport protocol does not
|
||||
* need fork(2), or a struct child_process object if it does. Once done,
|
||||
@@ -769,7 +812,8 @@ struct child_process *git_connect(int fd[2], const char *url,
|
||||
conn->in = conn->out = -1;
|
||||
if (protocol == PROTO_SSH) {
|
||||
const char *ssh;
|
||||
int putty = 0, tortoiseplink = 0;
|
||||
int needs_batch = 0;
|
||||
int port_option = 'p';
|
||||
char *ssh_host = hostandport;
|
||||
const char *port = NULL;
|
||||
transport_check_allowed("ssh");
|
||||
@@ -792,10 +836,10 @@ struct child_process *git_connect(int fd[2], const char *url,
|
||||
}
|
||||
|
||||
ssh = get_ssh_command();
|
||||
if (!ssh) {
|
||||
const char *base;
|
||||
char *ssh_dup;
|
||||
|
||||
if (ssh)
|
||||
handle_ssh_variant(ssh, 1, &port_option,
|
||||
&needs_batch);
|
||||
else {
|
||||
/*
|
||||
* GIT_SSH is the no-shell version of
|
||||
* GIT_SSH_COMMAND (and must remain so for
|
||||
@@ -806,17 +850,10 @@ struct child_process *git_connect(int fd[2], const char *url,
|
||||
ssh = getenv("GIT_SSH");
|
||||
if (!ssh)
|
||||
ssh = "ssh";
|
||||
|
||||
ssh_dup = xstrdup(ssh);
|
||||
base = basename(ssh_dup);
|
||||
|
||||
tortoiseplink = !strcasecmp(base, "tortoiseplink") ||
|
||||
!strcasecmp(base, "tortoiseplink.exe");
|
||||
putty = tortoiseplink ||
|
||||
!strcasecmp(base, "plink") ||
|
||||
!strcasecmp(base, "plink.exe");
|
||||
|
||||
free(ssh_dup);
|
||||
else
|
||||
handle_ssh_variant(ssh, 0,
|
||||
&port_option,
|
||||
&needs_batch);
|
||||
}
|
||||
|
||||
argv_array_push(&conn->args, ssh);
|
||||
@@ -824,11 +861,11 @@ struct child_process *git_connect(int fd[2], const char *url,
|
||||
argv_array_push(&conn->args, "-4");
|
||||
else if (flags & CONNECT_IPV6)
|
||||
argv_array_push(&conn->args, "-6");
|
||||
if (tortoiseplink)
|
||||
if (needs_batch)
|
||||
argv_array_push(&conn->args, "-batch");
|
||||
if (port) {
|
||||
/* P is for PuTTY, p is for OpenSSH */
|
||||
argv_array_push(&conn->args, putty ? "-P" : "-p");
|
||||
argv_array_pushf(&conn->args,
|
||||
"-%c", port_option);
|
||||
argv_array_push(&conn->args, port);
|
||||
}
|
||||
argv_array_push(&conn->args, ssh_host);
|
||||
|
||||
@@ -386,6 +386,47 @@ test_expect_success 'tortoiseplink is like putty, with extra arguments' '
|
||||
expect_ssh "-batch -P 123" myhost src
|
||||
'
|
||||
|
||||
test_expect_success 'double quoted plink.exe in GIT_SSH_COMMAND' '
|
||||
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" &&
|
||||
GIT_SSH_COMMAND="\"$TRASH_DIRECTORY/plink.exe\" -v" \
|
||||
git clone "[myhost:123]:src" ssh-bracket-clone-plink-3 &&
|
||||
expect_ssh "-v -P 123" myhost src
|
||||
'
|
||||
|
||||
SQ="'"
|
||||
test_expect_success 'single quoted plink.exe in GIT_SSH_COMMAND' '
|
||||
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" &&
|
||||
GIT_SSH_COMMAND="$SQ$TRASH_DIRECTORY/plink.exe$SQ -v" \
|
||||
git clone "[myhost:123]:src" ssh-bracket-clone-plink-4 &&
|
||||
expect_ssh "-v -P 123" myhost src
|
||||
'
|
||||
|
||||
test_expect_success 'GIT_SSH_VARIANT overrides plink detection' '
|
||||
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
|
||||
GIT_SSH_VARIANT=ssh \
|
||||
git clone "[myhost:123]:src" ssh-bracket-clone-variant-1 &&
|
||||
expect_ssh "-p 123" myhost src
|
||||
'
|
||||
|
||||
test_expect_success 'ssh.variant overrides plink detection' '
|
||||
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
|
||||
git -c ssh.variant=ssh \
|
||||
clone "[myhost:123]:src" ssh-bracket-clone-variant-2 &&
|
||||
expect_ssh "-p 123" myhost src
|
||||
'
|
||||
|
||||
test_expect_success 'GIT_SSH_VARIANT overrides plink detection to plink' '
|
||||
GIT_SSH_VARIANT=plink \
|
||||
git clone "[myhost:123]:src" ssh-bracket-clone-variant-3 &&
|
||||
expect_ssh "-P 123" myhost src
|
||||
'
|
||||
|
||||
test_expect_success 'GIT_SSH_VARIANT overrides plink to tortoiseplink' '
|
||||
GIT_SSH_VARIANT=tortoiseplink \
|
||||
git clone "[myhost:123]:src" ssh-bracket-clone-variant-4 &&
|
||||
expect_ssh "-batch -P 123" myhost src
|
||||
'
|
||||
|
||||
# Reset the GIT_SSH environment variable for clone tests.
|
||||
setup_ssh_wrapper
|
||||
|
||||
|
||||
Reference in New Issue
Block a user