Merge branch 'js/var-git-shell-path'
"git var GIT_SHELL_PATH" should report the path to the shell used to spawn external commands, but it didn't do so on Windows, which has been corrected. * js/var-git-shell-path: var(win32): do report the GIT_SHELL_PATH that is actually used run-command: declare the `git_shell_path()` function globally run-command(win32): resolve the path to the Unix shell early mingw(is_msys2_sh): handle forward slashes in the `sh.exe` path, too win32: override `fspathcmp()` with a directory separator-aware version strvec: declare the `strvec_push_nodup()` function globally run-command: refactor getting the Unix shell path into its own functionmaint
commit
76e018b9a1
|
@ -12,6 +12,7 @@
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
#include "run-command.h"
|
||||||
|
|
||||||
static const char var_usage[] = "git var (-l | <variable>)";
|
static const char var_usage[] = "git var (-l | <variable>)";
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ static char *default_branch(int ident_flag UNUSED)
|
||||||
|
|
||||||
static char *shell_path(int ident_flag UNUSED)
|
static char *shell_path(int ident_flag UNUSED)
|
||||||
{
|
{
|
||||||
return xstrdup(SHELL_PATH);
|
return git_shell_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *git_attr_val_system(int ident_flag UNUSED)
|
static char *git_attr_val_system(int ident_flag UNUSED)
|
||||||
|
|
|
@ -1546,7 +1546,7 @@ static int is_msys2_sh(const char *cmd)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ends_with(cmd, "\\sh.exe")) {
|
if (ends_with(cmd, "\\sh.exe") || ends_with(cmd, "/sh.exe")) {
|
||||||
static char *sh;
|
static char *sh;
|
||||||
|
|
||||||
if (!sh)
|
if (!sh)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "../../git-compat-util.h"
|
#include "../../git-compat-util.h"
|
||||||
|
#include "../../environment.h"
|
||||||
|
|
||||||
int win32_has_dos_drive_prefix(const char *path)
|
int win32_has_dos_drive_prefix(const char *path)
|
||||||
{
|
{
|
||||||
|
@ -50,3 +51,39 @@ int win32_offset_1st_component(const char *path)
|
||||||
|
|
||||||
return pos + is_dir_sep(*pos) - path;
|
return pos + is_dir_sep(*pos) - path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int win32_fspathncmp(const char *a, const char *b, size_t count)
|
||||||
|
{
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (!count--)
|
||||||
|
return 0;
|
||||||
|
if (!*a)
|
||||||
|
return *b ? -1 : 0;
|
||||||
|
if (!*b)
|
||||||
|
return +1;
|
||||||
|
|
||||||
|
if (is_dir_sep(*a)) {
|
||||||
|
if (!is_dir_sep(*b))
|
||||||
|
return -1;
|
||||||
|
a++;
|
||||||
|
b++;
|
||||||
|
continue;
|
||||||
|
} else if (is_dir_sep(*b))
|
||||||
|
return +1;
|
||||||
|
|
||||||
|
diff = ignore_case ?
|
||||||
|
(unsigned char)tolower(*a) - (int)(unsigned char)tolower(*b) :
|
||||||
|
(unsigned char)*a - (int)(unsigned char)*b;
|
||||||
|
if (diff)
|
||||||
|
return diff;
|
||||||
|
a++;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int win32_fspathcmp(const char *a, const char *b)
|
||||||
|
{
|
||||||
|
return win32_fspathncmp(a, b, (size_t)-1);
|
||||||
|
}
|
||||||
|
|
|
@ -29,5 +29,9 @@ static inline int win32_has_dir_sep(const char *path)
|
||||||
#define has_dir_sep(path) win32_has_dir_sep(path)
|
#define has_dir_sep(path) win32_has_dir_sep(path)
|
||||||
int win32_offset_1st_component(const char *path);
|
int win32_offset_1st_component(const char *path);
|
||||||
#define offset_1st_component win32_offset_1st_component
|
#define offset_1st_component win32_offset_1st_component
|
||||||
|
int win32_fspathcmp(const char *a, const char *b);
|
||||||
|
#define fspathcmp win32_fspathcmp
|
||||||
|
int win32_fspathncmp(const char *a, const char *b, size_t count);
|
||||||
|
#define fspathncmp win32_fspathncmp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
4
dir.c
4
dir.c
|
@ -95,7 +95,7 @@ int count_slashes(const char *s)
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fspathcmp(const char *a, const char *b)
|
int git_fspathcmp(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
|
return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ int fspatheq(const char *a, const char *b)
|
||||||
return !fspathcmp(a, b);
|
return !fspathcmp(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fspathncmp(const char *a, const char *b, size_t count)
|
int git_fspathncmp(const char *a, const char *b, size_t count)
|
||||||
{
|
{
|
||||||
return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
|
return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
|
||||||
}
|
}
|
||||||
|
|
4
dir.h
4
dir.h
|
@ -541,9 +541,9 @@ int remove_dir_recursively(struct strbuf *path, int flag);
|
||||||
*/
|
*/
|
||||||
int remove_path(const char *path);
|
int remove_path(const char *path);
|
||||||
|
|
||||||
int fspathcmp(const char *a, const char *b);
|
int git_fspathcmp(const char *a, const char *b);
|
||||||
int fspatheq(const char *a, const char *b);
|
int fspatheq(const char *a, const char *b);
|
||||||
int fspathncmp(const char *a, const char *b, size_t count);
|
int git_fspathncmp(const char *a, const char *b, size_t count);
|
||||||
unsigned int fspathhash(const char *str);
|
unsigned int fspathhash(const char *str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -506,6 +506,14 @@ static inline int git_offset_1st_component(const char *path)
|
||||||
#define offset_1st_component git_offset_1st_component
|
#define offset_1st_component git_offset_1st_component
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef fspathcmp
|
||||||
|
#define fspathcmp git_fspathcmp
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef fspathncmp
|
||||||
|
#define fspathncmp git_fspathncmp
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef is_valid_path
|
#ifndef is_valid_path
|
||||||
#define is_valid_path(path) 1
|
#define is_valid_path(path) 1
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -274,17 +274,24 @@ int sane_execvp(const char *file, char * const argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *git_shell_path(void)
|
||||||
|
{
|
||||||
|
#ifndef GIT_WINDOWS_NATIVE
|
||||||
|
return xstrdup(SHELL_PATH);
|
||||||
|
#else
|
||||||
|
char *p = locate_in_PATH("sh");
|
||||||
|
convert_slashes(p);
|
||||||
|
return p;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static const char **prepare_shell_cmd(struct strvec *out, const char **argv)
|
static const char **prepare_shell_cmd(struct strvec *out, const char **argv)
|
||||||
{
|
{
|
||||||
if (!argv[0])
|
if (!argv[0])
|
||||||
BUG("shell command is empty");
|
BUG("shell command is empty");
|
||||||
|
|
||||||
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
|
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
|
||||||
#ifndef GIT_WINDOWS_NATIVE
|
strvec_push_nodup(out, git_shell_path());
|
||||||
strvec_push(out, SHELL_PATH);
|
|
||||||
#else
|
|
||||||
strvec_push(out, "sh");
|
|
||||||
#endif
|
|
||||||
strvec_push(out, "-c");
|
strvec_push(out, "-c");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -195,6 +195,11 @@ int is_executable(const char *name);
|
||||||
*/
|
*/
|
||||||
int exists_in_PATH(const char *command);
|
int exists_in_PATH(const char *command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the path that is used to execute Unix shell command-lines.
|
||||||
|
*/
|
||||||
|
char *git_shell_path(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a sub-process. Takes a pointer to a `struct child_process`
|
* Start a sub-process. Takes a pointer to a `struct child_process`
|
||||||
* that specifies the details and returns pipe FDs (if requested).
|
* that specifies the details and returns pipe FDs (if requested).
|
||||||
|
|
2
strvec.c
2
strvec.c
|
@ -10,7 +10,7 @@ void strvec_init(struct strvec *array)
|
||||||
memcpy(array, &blank, sizeof(*array));
|
memcpy(array, &blank, sizeof(*array));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void strvec_push_nodup(struct strvec *array, const char *value)
|
void strvec_push_nodup(struct strvec *array, char *value)
|
||||||
{
|
{
|
||||||
if (array->v == empty_strvec)
|
if (array->v == empty_strvec)
|
||||||
array->v = NULL;
|
array->v = NULL;
|
||||||
|
|
3
strvec.h
3
strvec.h
|
@ -46,6 +46,9 @@ void strvec_init(struct strvec *);
|
||||||
/* Push a copy of a string onto the end of the array. */
|
/* Push a copy of a string onto the end of the array. */
|
||||||
const char *strvec_push(struct strvec *, const char *);
|
const char *strvec_push(struct strvec *, const char *);
|
||||||
|
|
||||||
|
/* Push an allocated string onto the end of the array, taking ownership. */
|
||||||
|
void strvec_push_nodup(struct strvec *array, char *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a string and push it onto the end of the array. This is a
|
* Format a string and push it onto the end of the array. This is a
|
||||||
* convenience wrapper combining `strbuf_addf` and `strvec_push`.
|
* convenience wrapper combining `strbuf_addf` and `strvec_push`.
|
||||||
|
|
|
@ -157,7 +157,7 @@ test_expect_success POSIXPERM 'GIT_SHELL_PATH points to a valid executable' '
|
||||||
test_expect_success MINGW 'GIT_SHELL_PATH points to a suitable shell' '
|
test_expect_success MINGW 'GIT_SHELL_PATH points to a suitable shell' '
|
||||||
shellpath=$(git var GIT_SHELL_PATH) &&
|
shellpath=$(git var GIT_SHELL_PATH) &&
|
||||||
case "$shellpath" in
|
case "$shellpath" in
|
||||||
*sh) ;;
|
[A-Z]:/*/sh.exe) test -f "$shellpath";;
|
||||||
*) return 1;;
|
*) return 1;;
|
||||||
esac
|
esac
|
||||||
'
|
'
|
||||||
|
|
Loading…
Reference in New Issue