A new version of the patch, which spells out more its intent and may actually work in Windows. Any comment welcome, Thanks, Stefan Stefan Beller (1): submodule: Port resolve_relative_url from shell to C builtin/submodule--helper.c | 151 ++++++++++++++++++++++++++++++++++++++++++++ git-submodule.sh | 81 ++---------------------- 2 files changed, 155 insertions(+), 77 deletions(-) interdiff to previous version: diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index f48b5b5..b925bed 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -31,6 +31,36 @@ static const char *get_default_remote(void) return xstrdup(dest); } +static int has_same_dir_prefix(const char *str, const char **out) +{ +#ifdef GIT_WINDOWS_NATIVE + return skip_prefix(str, "./", out) + || skip_prefix(str, ".\\", out); +#else + return skip_prefix(str, "./", out); +#endif +} + +static int has_upper_dir_prefix(const char *str, const char **out) +{ +#ifdef GIT_WINDOWS_NATIVE + return skip_prefix(str, "../", out) + || skip_prefix(str, "..\\", out); +#else + return skip_prefix(str, "../", out); +#endif +} + +static char *last_dir_separator(const char *str) +{ +#ifdef GIT_WINDOWS_NATIVE + return strrchr(str, "/") + || strrchr(str, "\\"); +#else + return strrchr(str, '/'); +#endif +} + /* * The function takes at most 2 arguments. The first argument is the * URL that navigates to the submodule origin repo. When relative, this URL @@ -64,13 +94,14 @@ static const char *relative_url(const char *url, const char *up_path) /* the repository is its own authoritative upstream */ remoteurl = xgetcwd(); - if (strip_suffix(remoteurl, "/", &len)) + len = strlen(remoteurl); + if (is_dir_sep(remoteurl[len])) remoteurl[len] = '\0'; - if (strchr(remoteurl, ':') || skip_prefix(remoteurl, "/", &out)) + if (strchr(remoteurl, ':') || is_dir_sep(*remoteurl)) is_relative = 0; - else if (skip_prefix(remoteurl, "./", &out) || - skip_prefix(remoteurl, "../", &out)) + else if (has_same_dir_prefix(remoteurl, &out) || + has_upper_dir_prefix(remoteurl, &out)) is_relative = 1; else { is_relative = 1; @@ -80,11 +111,11 @@ static const char *relative_url(const char *url, const char *up_path) } while (url) { - if (skip_prefix(url, "../", &out)) { + if (has_upper_dir_prefix(url, &out)) { char *rfind; url = out; - rfind = strrchr(remoteurl, '/'); + rfind = last_dir_separator(remoteurl); if (rfind) *rfind = '\0'; else { @@ -99,7 +130,7 @@ static const char *relative_url(const char *url, const char *up_path) remoteurl = "."; } } - } else if (skip_prefix(url, "./", &out)) + } else if (has_same_dir_prefix(url, &out)) url = out; else break; @@ -107,7 +138,7 @@ static const char *relative_url(const char *url, const char *up_path) strbuf_reset(&sb); strbuf_addf(&sb, "%s%s%s", remoteurl, sep, url); - if (!skip_prefix(sb.buf, "./", &out)) + if (!has_same_dir_prefix(sb.buf, &out)) out = sb.buf; out = xstrdup(out); -- 2.7.0.rc1.2.gfc39790.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html