diff options
author | Johannes Sixt <j6t@kdbg.org> | 2016-12-14 20:37:38 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-12-16 13:10:43 -0800 |
commit | 7814fbe3f1e7cea1a675408df7b5dd1f5be731cc (patch) | |
tree | ef2f4a7e48adbaf3e170a0ea46eb8c23f765ddab /path.c | |
parent | 0202c411edc25940cc381bf317badcdf67670be4 (diff) | |
download | git-7814fbe3f1e7cea1a675408df7b5dd1f5be731cc.tar.gz git-7814fbe3f1e7cea1a675408df7b5dd1f5be731cc.tar.xz |
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>
Diffstat (limited to 'path.c')
-rw-r--r-- | path.c | 23 |
1 files changed, 14 insertions, 9 deletions
@@ -961,7 +961,7 @@ const char *remove_leading_path(const char *in, const char *prefix) * * Performs the following normalizations on src, storing the result in dst: * - Ensures that components are separated by '/' (Windows only) - * - Squashes sequences of '/'. + * - Squashes sequences of '/' except "//server/share" on Windows * - Removes "." components. * - Removes ".." components, and the components the precede them. * 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) int normalize_path_copy_len(char *dst, const char *src, int *prefix_len) { char *dst0; - int i; + const char *end; - for (i = has_dos_drive_prefix(src); i > 0; i--) - *dst++ = *src++; + /* + * Copy initial part of absolute path: "/", "C:/", "//server/share/". + */ + end = src + offset_1st_component(src); + while (src < end) { + char c = *src++; + if (is_dir_sep(c)) + c = '/'; + *dst++ = c; + } dst0 = dst; - if (is_dir_sep(*src)) { - *dst++ = '/'; - while (is_dir_sep(*src)) - src++; - } + while (is_dir_sep(*src)) + src++; for (;;) { char c = *src; |