mirror of
https://github.com/git/git.git
synced 2024-11-23 18:05:29 +08:00
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 function
This commit is contained in:
commit
76e018b9a1
@ -12,6 +12,7 @@
|
||||
#include "refs.h"
|
||||
#include "path.h"
|
||||
#include "strbuf.h"
|
||||
#include "run-command.h"
|
||||
|
||||
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)
|
||||
{
|
||||
return xstrdup(SHELL_PATH);
|
||||
return git_shell_path();
|
||||
}
|
||||
|
||||
static char *git_attr_val_system(int ident_flag UNUSED)
|
||||
|
@ -1546,7 +1546,7 @@ static int is_msys2_sh(const char *cmd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ends_with(cmd, "\\sh.exe")) {
|
||||
if (ends_with(cmd, "\\sh.exe") || ends_with(cmd, "/sh.exe")) {
|
||||
static char *sh;
|
||||
|
||||
if (!sh)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "../../git-compat-util.h"
|
||||
#include "../../environment.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
int win32_offset_1st_component(const char *path);
|
||||
#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
|
||||
|
4
dir.c
4
dir.c
@ -95,7 +95,7 @@ int count_slashes(const char *s)
|
||||
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);
|
||||
}
|
||||
@ -105,7 +105,7 @@ int fspatheq(const char *a, const char *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);
|
||||
}
|
||||
|
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 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 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);
|
||||
|
||||
/*
|
||||
|
@ -506,6 +506,14 @@ static inline int git_offset_1st_component(const char *path)
|
||||
#define offset_1st_component git_offset_1st_component
|
||||
#endif
|
||||
|
||||
#ifndef fspathcmp
|
||||
#define fspathcmp git_fspathcmp
|
||||
#endif
|
||||
|
||||
#ifndef fspathncmp
|
||||
#define fspathncmp git_fspathncmp
|
||||
#endif
|
||||
|
||||
#ifndef is_valid_path
|
||||
#define is_valid_path(path) 1
|
||||
#endif
|
||||
|
@ -274,17 +274,24 @@ int sane_execvp(const char *file, char * const argv[])
|
||||
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)
|
||||
{
|
||||
if (!argv[0])
|
||||
BUG("shell command is empty");
|
||||
|
||||
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
|
||||
#ifndef GIT_WINDOWS_NATIVE
|
||||
strvec_push(out, SHELL_PATH);
|
||||
#else
|
||||
strvec_push(out, "sh");
|
||||
#endif
|
||||
strvec_push_nodup(out, git_shell_path());
|
||||
strvec_push(out, "-c");
|
||||
|
||||
/*
|
||||
|
@ -195,6 +195,11 @@ int is_executable(const char *name);
|
||||
*/
|
||||
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`
|
||||
* 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));
|
||||
}
|
||||
|
||||
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)
|
||||
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. */
|
||||
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
|
||||
* 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' '
|
||||
shellpath=$(git var GIT_SHELL_PATH) &&
|
||||
case "$shellpath" in
|
||||
*sh) ;;
|
||||
[A-Z]:/*/sh.exe) test -f "$shellpath";;
|
||||
*) return 1;;
|
||||
esac
|
||||
'
|
||||
|
Loading…
Reference in New Issue
Block a user