Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying at runtime which POSIX shell to use #3301

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Documentation/config/core.txt
Original file line number Diff line number Diff line change
Expand Up @@ -628,3 +628,7 @@ core.abbrev::
If set to "no", no abbreviation is made and the object names
are shown in their full length.
The minimum length is 4.

core.shell::
Set the absolute path to the executable to use as a POSIX shell;
This will also set/override the environment variable `SHELL`.
10 changes: 10 additions & 0 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,10 @@ static char *path_lookup(const char *cmd, int exe_only)
if (strpbrk(cmd, "/\\"))
return xstrdup(cmd);

if (!strcmp(cmd, "sh") &&
(prog = xstrdup_or_null(get_shell_path(NULL))))
return prog;

path = mingw_getenv("PATH");
if (!path)
return NULL;
Expand Down Expand Up @@ -1463,6 +1467,12 @@ static int is_msys2_sh(const char *cmd)
if (ret >= 0)
return ret;

if (get_shell_path(NULL)) {
/* Assume an overridden shell is not MSYS2 */
ret = 0;
return ret;
}

p = path_lookup(cmd, 0);
if (!p)
ret = 0;
Expand Down
2 changes: 1 addition & 1 deletion help.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ void get_version_info(struct strbuf *buf, int show_build_options)
strbuf_addstr(buf, "no commit associated with this build\n");
strbuf_addf(buf, "sizeof-long: %d\n", (int)sizeof(long));
strbuf_addf(buf, "sizeof-size_t: %d\n", (int)sizeof(size_t));
strbuf_addf(buf, "shell-path: %s\n", SHELL_PATH);
strbuf_addf(buf, "shell-path: %s\n", get_shell_path(SHELL_PATH));
/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */
}
}
Expand Down
20 changes: 17 additions & 3 deletions run-command.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@
#include "quote.h"
#include "config.h"

const char *get_shell_path(const char *fallback)
{
static const char *shell;
static int initialized;

if (!initialized) {
if (!git_config_get_pathname("core.shell", &shell))
setenv("SHELL", shell, 1);
initialized = 1;
}

return shell ? shell : fallback;
}

void child_process_init(struct child_process *child)
{
memset(child, 0, sizeof(*child));
Expand Down Expand Up @@ -271,9 +285,9 @@ static const char **prepare_shell_cmd(struct strvec *out, const char **argv)

if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
#ifndef GIT_WINDOWS_NATIVE
strvec_push(out, SHELL_PATH);
strvec_push(out, get_shell_path(SHELL_PATH));
#else
strvec_push(out, "sh");
strvec_push(out, get_shell_path("sh"));
#endif
strvec_push(out, "-c");

Expand Down Expand Up @@ -411,7 +425,7 @@ static int prepare_cmd(struct strvec *out, const struct child_process *cmd)
* Add SHELL_PATH so in the event exec fails with ENOEXEC we can
* attempt to interpret the command with 'sh'.
*/
strvec_push(out, SHELL_PATH);
strvec_push(out, get_shell_path(SHELL_PATH));

if (cmd->git_cmd) {
prepare_git_cmd(out, cmd->argv);
Expand Down
5 changes: 5 additions & 0 deletions run-command.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,4 +483,9 @@ int run_processes_parallel_tr2(int n, get_next_task_fn, start_failure_fn,
task_finished_fn, void *pp_cb,
const char *tr2_category, const char *tr2_label);

/*
* Get the path of the POSIX shell to use in `start_command()`.
*/
const char *get_shell_path(const char *fallback);

#endif
14 changes: 14 additions & 0 deletions t/t0061-run-command.sh
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,18 @@ test_expect_success MINGW 'can spawn .bat with argv[0] containing spaces' '
grep "git-upload-pack" out
'

SQ="'"
test_expect_success 'core.shell' '
test_config_global core.shell "$GIT_EXEC_PATH/git$X" &&
test_must_fail git -c alias.eq="!a.b=c" eq 2>actual &&
grep "${SQ}a.b=c${SQ} is not a git command" actual
'

test_expect_success MINGW 'core.shell executes scripts' '
test_config_global core.shell "$GIT_EXEC_PATH/git$X" &&
echo "#!/bin/sh" >script &&
test_must_fail git -c alias.s="!./script" s 2>actual &&
grep "${SQ}./script${SQ} is not a git command" actual
'

test_done