Skip to content

Commit 149f67a

Browse files
committed
Allow overriding which POSIX shell to use
Right now, the compiled-in default is used always, which can be overridden at compile time via the `SHELL_PATH` variable. However, in Git for Windows' context, there is a scenario where this is not good enough: the BusyBox flavor of MinGit wants to use BusyBox' `ash` instead. To allow for that, let's introduce a new config variable: `core.shell`. Its value is expected to be the absolute path to a valid, working POSIX shell. This shell will be then used by `git.exe` whenever it needs to execute something via shell, such as moderately complex aliases. And it is not only Git that is expected to use that `ash`, it is also OpenSSH (e.g. when running any configured `ProxyCommand`): programs spawned from `git.exe` may need to run a shell and look at the environment variable `SHELL` for that. Therefore, let's set that, too. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent ebf3c04 commit 149f67a

File tree

5 files changed

+34
-4
lines changed

5 files changed

+34
-4
lines changed

Documentation/config/core.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,3 +628,7 @@ core.abbrev::
628628
If set to "no", no abbreviation is made and the object names
629629
are shown in their full length.
630630
The minimum length is 4.
631+
632+
core.shell::
633+
Set the absolute path to the executable to use as a POSIX shell;
634+
This will also set/override the environment variable `SHELL`.

help.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ void get_version_info(struct strbuf *buf, int show_build_options)
662662
strbuf_addstr(buf, "no commit associated with this build\n");
663663
strbuf_addf(buf, "sizeof-long: %d\n", (int)sizeof(long));
664664
strbuf_addf(buf, "sizeof-size_t: %d\n", (int)sizeof(size_t));
665-
strbuf_addf(buf, "shell-path: %s\n", SHELL_PATH);
665+
strbuf_addf(buf, "shell-path: %s\n", get_shell_path(SHELL_PATH));
666666
/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */
667667
}
668668
}

run-command.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@
99
#include "quote.h"
1010
#include "config.h"
1111

12+
const char *get_shell_path(const char *fallback)
13+
{
14+
static const char *shell;
15+
static int initialized;
16+
17+
if (!initialized) {
18+
if (!git_config_get_pathname("core.shell", &shell))
19+
setenv("SHELL", shell, 1);
20+
initialized = 1;
21+
}
22+
23+
return shell ? shell : fallback;
24+
}
25+
1226
void child_process_init(struct child_process *child)
1327
{
1428
memset(child, 0, sizeof(*child));
@@ -271,9 +285,9 @@ static const char **prepare_shell_cmd(struct strvec *out, const char **argv)
271285

272286
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
273287
#ifndef GIT_WINDOWS_NATIVE
274-
strvec_push(out, SHELL_PATH);
288+
strvec_push(out, get_shell_path(SHELL_PATH));
275289
#else
276-
strvec_push(out, "sh");
290+
strvec_push(out, get_shell_path("sh"));
277291
#endif
278292
strvec_push(out, "-c");
279293

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

416430
if (cmd->git_cmd) {
417431
prepare_git_cmd(out, cmd->argv);

run-command.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,4 +483,9 @@ int run_processes_parallel_tr2(int n, get_next_task_fn, start_failure_fn,
483483
task_finished_fn, void *pp_cb,
484484
const char *tr2_category, const char *tr2_label);
485485

486+
/*
487+
* Get the path of the POSIX shell to use in `start_command()`.
488+
*/
489+
const char *get_shell_path(const char *fallback);
490+
486491
#endif

t/t0061-run-command.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,11 @@ test_expect_success MINGW 'can spawn .bat with argv[0] containing spaces' '
233233
grep "git-upload-pack" out
234234
'
235235

236+
SQ="'"
237+
test_expect_success 'core.shell' '
238+
test_config_global core.shell "$GIT_EXEC_PATH/git$X" &&
239+
test_must_fail git -c alias.eq="!a.b=c" eq 2>actual &&
240+
grep "${SQ}a.b=c${SQ} is not a git command" actual
241+
'
242+
236243
test_done

0 commit comments

Comments
 (0)