Skip to content

Commit faaf232

Browse files
committed
Merge branch 'unc-path-w-backslashes'
This topic branch addresses a problem identified in #439: while cloning/fetching/pushing from "POSIX-ified UNC paths" (i.e. UNC paths whose backslashes have been converted to forward slashes) works for some time now, true UNC paths (with backslashes left intact) were handled incorrectly. Example: git clone //myserver/folder/repo.git works, but git clone \\myserver\folder\repo.git (in CMD; in Git Bash, the backslashes would need to be doubled) used to fail. The reason was an unexpected difference in command-line handling between Win32 executables and MSYS2 ones (such as the shell that is used by git-clone.exe to spawn git-upload-pack.exe). This topic branch features a workaround *just* for the case where Git passes stuff through sh.exe (which covers quite a few use cases, though). Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 2aba389 + 81e2795 commit faaf232

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

compat/mingw.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ char *mingw_getcwd(char *pointer, int len)
10661066
* See http://msdn2.microsoft.com/en-us/library/17w5ykft(vs.71).aspx
10671067
* (Parsing C++ Command-Line Arguments)
10681068
*/
1069-
static const char *quote_arg(const char *arg)
1069+
static const char *quote_arg_msvc(const char *arg)
10701070
{
10711071
/* count chars to quote */
10721072
int len = 0, n = 0;
@@ -1121,6 +1121,37 @@ static const char *quote_arg(const char *arg)
11211121
return q;
11221122
}
11231123

1124+
#include "quote.h"
1125+
1126+
static const char *quote_arg_sh(const char *arg)
1127+
{
1128+
struct strbuf buf = STRBUF_INIT;
1129+
const char *p2 = arg, *p;
1130+
1131+
for (p = arg; *p; p++) {
1132+
int ws = isspace(*p);
1133+
if (!ws && *p != '\\' && *p != '"')
1134+
continue;
1135+
if (!buf.len)
1136+
strbuf_addch(&buf, '"');
1137+
if (p != p2)
1138+
strbuf_add(&buf, p2, p - p2);
1139+
if (!ws)
1140+
strbuf_addch(&buf, '\\');
1141+
p2 = p;
1142+
}
1143+
1144+
if (p == arg)
1145+
strbuf_addch(&buf, '"');
1146+
else if (!buf.len)
1147+
return arg;
1148+
else
1149+
strbuf_add(&buf, p2, p - p2),
1150+
1151+
strbuf_addch(&buf, '"');
1152+
return strbuf_detach(&buf, 0);
1153+
}
1154+
11241155
static const char *parse_interpreter(const char *cmd)
11251156
{
11261157
static char buf[100];
@@ -1547,6 +1578,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
15471578
BOOL ret;
15481579
HANDLE cons;
15491580
const char *strace_env;
1581+
const char *(*quote_arg)(const char *arg) =
1582+
*argv && !strcmp("sh", *argv) ? quote_arg_sh : quote_arg_msvc;
15501583

15511584
if (!atexit_handler_initialized) {
15521585
atexit_handler_initialized = 1;

t/t5580-clone-push-unc.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ esac
2525

2626
test_expect_success 'clone into absolute path lacking a drive prefix' '
2727
USINGBACKSLASHES="$(echo "$WITHOUTDRIVE"/without-drive-prefix |
28-
tr / \\)" &&
28+
tr / \\\\)" &&
2929
git clone . "$USINGBACKSLASHES" &&
3030
test -f without-drive-prefix/.git/HEAD
3131
'
@@ -43,6 +43,11 @@ test_expect_success clone '
4343
git clone "file://$UNCPATH" clone
4444
'
4545

46+
test_expect_success 'clone with backslashed path' '
47+
BACKSLASHED="$(echo "$UNCPATH" | tr / \\\\)" &&
48+
git clone "$BACKSLASHED" backslashed
49+
'
50+
4651
test_expect_success push '
4752
(
4853
cd clone &&

0 commit comments

Comments
 (0)