Skip to content

Commit 7814fbe

Browse files
j6tgitster
authored andcommitted
normalize_path_copy(): 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(). Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 0202c41 commit 7814fbe

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

path.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ const char *remove_leading_path(const char *in, const char *prefix)
961961
*
962962
* Performs the following normalizations on src, storing the result in dst:
963963
* - Ensures that components are separated by '/' (Windows only)
964-
* - Squashes sequences of '/'.
964+
* - Squashes sequences of '/' except "//server/share" on Windows
965965
* - Removes "." components.
966966
* - Removes ".." components, and the components the precede them.
967967
* Returns failure (non-zero) if a ".." component appears as first path
@@ -984,17 +984,22 @@ const char *remove_leading_path(const char *in, const char *prefix)
984984
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
985985
{
986986
char *dst0;
987-
int i;
987+
const char *end;
988988

989-
for (i = has_dos_drive_prefix(src); i > 0; i--)
990-
*dst++ = *src++;
989+
/*
990+
* Copy initial part of absolute path: "/", "C:/", "//server/share/".
991+
*/
992+
end = src + offset_1st_component(src);
993+
while (src < end) {
994+
char c = *src++;
995+
if (is_dir_sep(c))
996+
c = '/';
997+
*dst++ = c;
998+
}
991999
dst0 = dst;
9921000

993-
if (is_dir_sep(*src)) {
994-
*dst++ = '/';
995-
while (is_dir_sep(*src))
996-
src++;
997-
}
1001+
while (is_dir_sep(*src))
1002+
src++;
9981003

9991004
for (;;) {
10001005
char c = *src;

0 commit comments

Comments
 (0)