diff --git a/builtin-clone.c b/builtin-clone.c index f4accbe541..7190952071 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -76,7 +76,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) path = mkpath("%s%s", repo, suffix[i]); if (!stat(path, &st) && S_ISDIR(st.st_mode)) { *is_bundle = 0; - return xstrdup(make_absolute_path(path)); + return xstrdup(make_nonrelative_path(path)); } } @@ -85,7 +85,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) path = mkpath("%s%s", repo, bundle_suffix[i]); if (!stat(path, &st) && S_ISREG(st.st_mode)) { *is_bundle = 1; - return xstrdup(make_absolute_path(path)); + return xstrdup(make_nonrelative_path(path)); } } diff --git a/cache.h b/cache.h index 092a997b07..0a63c0eae6 100644 --- a/cache.h +++ b/cache.h @@ -524,6 +524,7 @@ static inline int is_absolute_path(const char *path) return path[0] == '/'; } const char *make_absolute_path(const char *path); +const char *make_nonrelative_path(const char *path); /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ extern int sha1_object_info(const unsigned char *, unsigned long *); diff --git a/path.c b/path.c index b7c24a2aac..4945f2abc5 100644 --- a/path.c +++ b/path.c @@ -291,6 +291,42 @@ int adjust_shared_perm(const char *path) return 0; } +static const char *get_pwd_cwd(void) +{ + static char cwd[PATH_MAX + 1]; + char *pwd; + struct stat cwd_stat, pwd_stat; + if (getcwd(cwd, PATH_MAX) == NULL) + return NULL; + pwd = getenv("PWD"); + if (pwd && strcmp(pwd, cwd)) { + stat(cwd, &cwd_stat); + if (!stat(pwd, &pwd_stat) && + pwd_stat.st_dev == cwd_stat.st_dev && + pwd_stat.st_ino == cwd_stat.st_ino) { + strlcpy(cwd, pwd, PATH_MAX); + } + } + return cwd; +} + +const char *make_nonrelative_path(const char *path) +{ + static char buf[PATH_MAX + 1]; + + if (path[0] == '/') { + if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) + die ("Too long path: %.*s", 60, path); + } else { + const char *cwd = get_pwd_cwd(); + if (!cwd) + die("Cannot determine the current working directory"); + if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX) + die ("Too long path: %.*s", 60, path); + } + return buf; +} + /* We allow "recursive" symbolic links. Only within reason, though. */ #define MAXDEPTH 5