Skip to content

Commit 76e018b

Browse files
committed
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
2 parents c7e8aae + 9ed143e commit 76e018b

File tree

12 files changed

+78
-13
lines changed

12 files changed

+78
-13
lines changed

builtin/var.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "refs.h"
1313
#include "path.h"
1414
#include "strbuf.h"
15+
#include "run-command.h"
1516

1617
static const char var_usage[] = "git var (-l | <variable>)";
1718

@@ -51,7 +52,7 @@ static char *default_branch(int ident_flag UNUSED)
5152

5253
static char *shell_path(int ident_flag UNUSED)
5354
{
54-
return xstrdup(SHELL_PATH);
55+
return git_shell_path();
5556
}
5657

5758
static char *git_attr_val_system(int ident_flag UNUSED)

compat/mingw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,7 @@ static int is_msys2_sh(const char *cmd)
15461546
return ret;
15471547
}
15481548

1549-
if (ends_with(cmd, "\\sh.exe")) {
1549+
if (ends_with(cmd, "\\sh.exe") || ends_with(cmd, "/sh.exe")) {
15501550
static char *sh;
15511551

15521552
if (!sh)

compat/win32/path-utils.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "../../git-compat-util.h"
2+
#include "../../environment.h"
23

34
int win32_has_dos_drive_prefix(const char *path)
45
{
@@ -50,3 +51,39 @@ int win32_offset_1st_component(const char *path)
5051

5152
return pos + is_dir_sep(*pos) - path;
5253
}
54+
55+
int win32_fspathncmp(const char *a, const char *b, size_t count)
56+
{
57+
int diff;
58+
59+
for (;;) {
60+
if (!count--)
61+
return 0;
62+
if (!*a)
63+
return *b ? -1 : 0;
64+
if (!*b)
65+
return +1;
66+
67+
if (is_dir_sep(*a)) {
68+
if (!is_dir_sep(*b))
69+
return -1;
70+
a++;
71+
b++;
72+
continue;
73+
} else if (is_dir_sep(*b))
74+
return +1;
75+
76+
diff = ignore_case ?
77+
(unsigned char)tolower(*a) - (int)(unsigned char)tolower(*b) :
78+
(unsigned char)*a - (int)(unsigned char)*b;
79+
if (diff)
80+
return diff;
81+
a++;
82+
b++;
83+
}
84+
}
85+
86+
int win32_fspathcmp(const char *a, const char *b)
87+
{
88+
return win32_fspathncmp(a, b, (size_t)-1);
89+
}

compat/win32/path-utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,9 @@ static inline int win32_has_dir_sep(const char *path)
2929
#define has_dir_sep(path) win32_has_dir_sep(path)
3030
int win32_offset_1st_component(const char *path);
3131
#define offset_1st_component win32_offset_1st_component
32+
int win32_fspathcmp(const char *a, const char *b);
33+
#define fspathcmp win32_fspathcmp
34+
int win32_fspathncmp(const char *a, const char *b, size_t count);
35+
#define fspathncmp win32_fspathncmp
3236

3337
#endif

dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ int count_slashes(const char *s)
9595
return cnt;
9696
}
9797

98-
int fspathcmp(const char *a, const char *b)
98+
int git_fspathcmp(const char *a, const char *b)
9999
{
100100
return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
101101
}
@@ -105,7 +105,7 @@ int fspatheq(const char *a, const char *b)
105105
return !fspathcmp(a, b);
106106
}
107107

108-
int fspathncmp(const char *a, const char *b, size_t count)
108+
int git_fspathncmp(const char *a, const char *b, size_t count)
109109
{
110110
return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
111111
}

dir.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,9 +541,9 @@ int remove_dir_recursively(struct strbuf *path, int flag);
541541
*/
542542
int remove_path(const char *path);
543543

544-
int fspathcmp(const char *a, const char *b);
544+
int git_fspathcmp(const char *a, const char *b);
545545
int fspatheq(const char *a, const char *b);
546-
int fspathncmp(const char *a, const char *b, size_t count);
546+
int git_fspathncmp(const char *a, const char *b, size_t count);
547547
unsigned int fspathhash(const char *str);
548548

549549
/*

git-compat-util.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,14 @@ static inline int git_offset_1st_component(const char *path)
506506
#define offset_1st_component git_offset_1st_component
507507
#endif
508508

509+
#ifndef fspathcmp
510+
#define fspathcmp git_fspathcmp
511+
#endif
512+
513+
#ifndef fspathncmp
514+
#define fspathncmp git_fspathncmp
515+
#endif
516+
509517
#ifndef is_valid_path
510518
#define is_valid_path(path) 1
511519
#endif

run-command.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,24 @@ int sane_execvp(const char *file, char * const argv[])
274274
return -1;
275275
}
276276

277+
char *git_shell_path(void)
278+
{
279+
#ifndef GIT_WINDOWS_NATIVE
280+
return xstrdup(SHELL_PATH);
281+
#else
282+
char *p = locate_in_PATH("sh");
283+
convert_slashes(p);
284+
return p;
285+
#endif
286+
}
287+
277288
static const char **prepare_shell_cmd(struct strvec *out, const char **argv)
278289
{
279290
if (!argv[0])
280291
BUG("shell command is empty");
281292

282293
if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
283-
#ifndef GIT_WINDOWS_NATIVE
284-
strvec_push(out, SHELL_PATH);
285-
#else
286-
strvec_push(out, "sh");
287-
#endif
294+
strvec_push_nodup(out, git_shell_path());
288295
strvec_push(out, "-c");
289296

290297
/*

run-command.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ int is_executable(const char *name);
195195
*/
196196
int exists_in_PATH(const char *command);
197197

198+
/**
199+
* Return the path that is used to execute Unix shell command-lines.
200+
*/
201+
char *git_shell_path(void);
202+
198203
/**
199204
* Start a sub-process. Takes a pointer to a `struct child_process`
200205
* that specifies the details and returns pipe FDs (if requested).

strvec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ void strvec_init(struct strvec *array)
1010
memcpy(array, &blank, sizeof(*array));
1111
}
1212

13-
static void strvec_push_nodup(struct strvec *array, const char *value)
13+
void strvec_push_nodup(struct strvec *array, char *value)
1414
{
1515
if (array->v == empty_strvec)
1616
array->v = NULL;

strvec.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ void strvec_init(struct strvec *);
4646
/* Push a copy of a string onto the end of the array. */
4747
const char *strvec_push(struct strvec *, const char *);
4848

49+
/* Push an allocated string onto the end of the array, taking ownership. */
50+
void strvec_push_nodup(struct strvec *array, char *value);
51+
4952
/**
5053
* Format a string and push it onto the end of the array. This is a
5154
* convenience wrapper combining `strbuf_addf` and `strvec_push`.

t/t0007-git-var.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ test_expect_success POSIXPERM 'GIT_SHELL_PATH points to a valid executable' '
157157
test_expect_success MINGW 'GIT_SHELL_PATH points to a suitable shell' '
158158
shellpath=$(git var GIT_SHELL_PATH) &&
159159
case "$shellpath" in
160-
*sh) ;;
160+
[A-Z]:/*/sh.exe) test -f "$shellpath";;
161161
*) return 1;;
162162
esac
163163
'

0 commit comments

Comments
 (0)