Skip to content

Commit 2174823

Browse files
j6tdscho
authored andcommitted
fix pushing to //server/share/dir on Windows
normalize_path_copy() is not prepared to keep the double-slash of a //server/share/dir kind of path, but treats it like a regular POSIX style path and transforms it to /server/share/dir. The bug manifests when 'git push //server/share/dir master' is run, because tmp_objdir_add_as_alternate() uses the path in normalized form when it registers the quarantine object database via link_alt_odb_entries(). Needless to say that the directory cannot be accessed using the wrongly normalized path. Fix it by skipping all of the root part, not just a potential drive prefix. offset_1st_component takes care of this, see the implementation in compat/mingw.c::mingw_offset_1st_component(). This fixes #979 Signed-off-by: Johannes Sixt <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 49830ad commit 2174823

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

path.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ const char *remove_leading_path(const char *in, const char *prefix)
996996
*
997997
* Performs the following normalizations on src, storing the result in dst:
998998
* - Ensures that components are separated by '/' (Windows only)
999-
* - Squashes sequences of '/'.
999+
* - Squashes sequences of '/' except "//server/share" on Windows
10001000
* - Removes "." components.
10011001
* - Removes ".." components, and the components the precede them.
10021002
* Returns failure (non-zero) if a ".." component appears as first path
@@ -1019,17 +1019,22 @@ const char *remove_leading_path(const char *in, const char *prefix)
10191019
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
10201020
{
10211021
char *dst0;
1022-
int i = has_unc_prefix(src);
1022+
const char *end;
10231023

1024-
for (i = i ? i : has_dos_drive_prefix(src); i > 0; i--)
1025-
*dst++ = *src++;
1024+
/*
1025+
* Copy initial part of absolute path: "/", "C:/", "//server/share/".
1026+
*/
1027+
end = src + offset_1st_component(src);
1028+
while (src < end) {
1029+
char c = *src++;
1030+
if (is_dir_sep(c))
1031+
c = '/';
1032+
*dst++ = c;
1033+
}
10261034
dst0 = dst;
10271035

1028-
if (is_dir_sep(*src)) {
1029-
*dst++ = '/';
1030-
while (is_dir_sep(*src))
1031-
src++;
1032-
}
1036+
while (is_dir_sep(*src))
1037+
src++;
10331038

10341039
for (;;) {
10351040
char c = *src;

t/t5580-clone-push-unc.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ test_expect_success clone '
3434
git clone "file://$UNCPATH" clone
3535
'
3636

37-
test_expect_failure push '
37+
test_expect_success push '
3838
(
3939
cd clone &&
4040
git checkout -b to-push &&

0 commit comments

Comments
 (0)