From 0602f3e916a2727dfc4954b81ce5aacd69d9692c Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Wed, 15 Dec 2010 22:02:36 +0700 Subject: Add struct pathspec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old pathspec structure remains as pathspec.raw[]. New things are stored in pathspec.items[]. There's no guarantee that the pathspec order in raw[] is exactly as in items[]. raw[] is external (source) data and is untouched by pathspec manipulation functions. It eases migration from old const char ** to this new struct. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- dir.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'dir.c') diff --git a/dir.c b/dir.c index 570b651a17..70d10bc3da 100644 --- a/dir.c +++ b/dir.c @@ -1151,3 +1151,34 @@ int remove_path(const char *name) return 0; } +int init_pathspec(struct pathspec *pathspec, const char **paths) +{ + const char **p = paths; + int i; + + memset(pathspec, 0, sizeof(*pathspec)); + if (!p) + return 0; + while (*p) + p++; + pathspec->raw = paths; + pathspec->nr = p - paths; + if (!pathspec->nr) + return 0; + + pathspec->items = xmalloc(sizeof(struct pathspec_item)*pathspec->nr); + for (i = 0; i < pathspec->nr; i++) { + struct pathspec_item *item = pathspec->items+i; + const char *path = paths[i]; + + item->match = path; + item->len = strlen(path); + } + return 0; +} + +void free_pathspec(struct pathspec *pathspec) +{ + free(pathspec->items); + pathspec->items = NULL; +} -- cgit v1.3 From bc96cc87dbb229cbdabfd93391e24ef168713a74 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Wed, 15 Dec 2010 22:02:44 +0700 Subject: tree_entry_interesting(): support depth limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed to replace pathspec_matches() in builtin/grep.c. max_depth == -1 means infinite depth. Depth limit is only effective when pathspec.recursive == 1. When pathspec.recursive == 0, the behavior depends on match functions: non-recursive for tree_entry_interesting() and recursive for match_pathspec{,_depth} Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- cache.h | 2 ++ dir.c | 15 +++++++++++++++ dir.h | 1 + tree-diff.c | 4 ++++ tree-walk.c | 19 ++++++++++++++++--- 5 files changed, 38 insertions(+), 3 deletions(-) (limited to 'dir.c') diff --git a/cache.h b/cache.h index a6456143b2..0cf0bac893 100644 --- a/cache.h +++ b/cache.h @@ -503,6 +503,8 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct struct pathspec { const char **raw; /* get_pathspec() result, not freed by free_pathspec() */ int nr; + int recursive:1; + int max_depth; struct pathspec_item { const char *match; int len; diff --git a/dir.c b/dir.c index 70d10bc3da..c3bddb60c8 100644 --- a/dir.c +++ b/dir.c @@ -87,6 +87,21 @@ int fill_directory(struct dir_struct *dir, const char **pathspec) return len; } +int within_depth(const char *name, int namelen, + int depth, int max_depth) +{ + const char *cp = name, *cpe = name + namelen; + + while (cp < cpe) { + if (*cp++ != '/') + continue; + depth++; + if (depth > max_depth) + return 0; + } + return 1; +} + /* * Does 'match' match the given name? * A match is found if diff --git a/dir.h b/dir.h index 72a764ed84..5fa3fbe4c5 100644 --- a/dir.h +++ b/dir.h @@ -65,6 +65,7 @@ struct dir_struct { #define MATCHED_FNMATCH 2 #define MATCHED_EXACTLY 3 extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen); +extern int within_depth(const char *name, int namelen, int depth, int max_depth); extern int fill_directory(struct dir_struct *dir, const char **pathspec); extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec); diff --git a/tree-diff.c b/tree-diff.c index 45a3845c0a..03dc5c8e70 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -146,6 +146,10 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, int all_t1_interesting = 0; int all_t2_interesting = 0; + /* Enable recursion indefinitely */ + opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE); + opt->pathspec.max_depth = -1; + strbuf_init(&base, PATH_MAX); strbuf_add(&base, base_str, baselen); diff --git a/tree-walk.c b/tree-walk.c index 83bede9527..33feafa964 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -1,6 +1,7 @@ #include "cache.h" #include "tree-walk.h" #include "unpack-trees.h" +#include "dir.h" #include "tree.h" static const char *get_mode(const char *str, unsigned int *modep) @@ -559,8 +560,13 @@ int tree_entry_interesting(const struct name_entry *entry, int pathlen, baselen = base->len; int never_interesting = -1; - if (!ps || !ps->nr) - return 2; + if (!ps->nr) { + if (!ps->recursive || ps->max_depth == -1) + return 2; + return !!within_depth(base->buf, baselen, + !!S_ISDIR(entry->mode), + ps->max_depth); + } pathlen = tree_entry_len(entry->path, entry->sha1); @@ -573,7 +579,14 @@ int tree_entry_interesting(const struct name_entry *entry, /* If it doesn't match, move along... */ if (!match_dir_prefix(base->buf, baselen, match, matchlen)) continue; - return 2; + + if (!ps->recursive || ps->max_depth == -1) + return 2; + + return !!within_depth(base->buf + matchlen + 1, + baselen - matchlen - 1, + !!S_ISDIR(entry->mode), + ps->max_depth); } /* Does the base match? */ -- cgit v1.3 From 86e4ca69e358836599d4eb0c0e217caa9c9e455b Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Wed, 15 Dec 2010 22:02:45 +0700 Subject: tree_entry_interesting(): fix depth limit with overlapping pathspecs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suppose we have two pathspecs 'a' and 'a/b' (both are dirs) and depth limit 1. In current code, pathspecs are checked in input order. When 'a/b' is checked against pathspec 'a', it fails depth limit and therefore is excluded, although it should match 'a/b' pathspec. This patch reorders all pathspecs alphabetically, then teaches tree_entry_interesting() to check against the deepest pathspec first, so depth limit of a shallower pathspec won't affect a deeper one. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- dir.c | 13 +++++++++++++ tree-walk.c | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'dir.c') diff --git a/dir.c b/dir.c index c3bddb60c8..5b4e2b1cb3 100644 --- a/dir.c +++ b/dir.c @@ -1166,6 +1166,15 @@ int remove_path(const char *name) return 0; } +static int pathspec_item_cmp(const void *a_, const void *b_) +{ + struct pathspec_item *a, *b; + + a = (struct pathspec_item *)a_; + b = (struct pathspec_item *)b_; + return strcmp(a->match, b->match); +} + int init_pathspec(struct pathspec *pathspec, const char **paths) { const char **p = paths; @@ -1189,6 +1198,10 @@ int init_pathspec(struct pathspec *pathspec, const char **paths) item->match = path; item->len = strlen(path); } + + qsort(pathspec->items, pathspec->nr, + sizeof(struct pathspec_item), pathspec_item_cmp); + return 0; } diff --git a/tree-walk.c b/tree-walk.c index 33feafa964..be8182c72f 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -570,7 +570,7 @@ int tree_entry_interesting(const struct name_entry *entry, pathlen = tree_entry_len(entry->path, entry->sha1); - for (i = 0; i < ps->nr; i++) { + for (i = ps->nr-1; i >= 0; i--) { const struct pathspec_item *item = ps->items+i; const char *match = item->match; int matchlen = item->len; -- cgit v1.3 From d38f28093ef795bef13d2fda6621b4952afb42db Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Wed, 15 Dec 2010 22:02:46 +0700 Subject: tree_entry_interesting(): support wildcard matching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit never_interesting optimization is disabled if there is any wildcard pathspec, even if it only matches exactly on trees. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- cache.h | 2 ++ dir.c | 3 +++ t/t4010-diff-pathspec.sh | 14 ++++++++++++++ tree-walk.c | 30 +++++++++++++++++++++++++++--- tree-walk.h | 2 +- 5 files changed, 47 insertions(+), 4 deletions(-) (limited to 'dir.c') diff --git a/cache.h b/cache.h index 0cf0bac893..800efa2328 100644 --- a/cache.h +++ b/cache.h @@ -503,11 +503,13 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct struct pathspec { const char **raw; /* get_pathspec() result, not freed by free_pathspec() */ int nr; + int has_wildcard:1; int recursive:1; int max_depth; struct pathspec_item { const char *match; int len; + int has_wildcard:1; } *items; }; diff --git a/dir.c b/dir.c index 5b4e2b1cb3..b6ccaf3703 100644 --- a/dir.c +++ b/dir.c @@ -1197,6 +1197,9 @@ int init_pathspec(struct pathspec *pathspec, const char **paths) item->match = path; item->len = strlen(path); + item->has_wildcard = !no_wildcard(path); + if (item->has_wildcard) + pathspec->has_wildcard = 1; } qsort(pathspec->items, pathspec->nr, diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index 94df7ae53a..4b120f8e23 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -70,4 +70,18 @@ test_expect_success 'diff-tree pathspec' ' test_cmp expected current ' +EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904 + +test_expect_success 'diff-tree with wildcard shows dir also matches' ' + git diff-tree --name-only $EMPTY_TREE $tree -- "f*" >result && + echo file0 >expected && + test_cmp expected result +' + +test_expect_success 'diff-tree -r with wildcard' ' + git diff-tree -r --name-only $EMPTY_TREE $tree -- "*file1" >result && + echo path1/file1 >expected && + test_cmp expected result +' + test_done diff --git a/tree-walk.c b/tree-walk.c index be8182c72f..ae7ac1a9f2 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -553,12 +553,12 @@ static int match_dir_prefix(const char *base, int baselen, * - negative for "no, and no subsequent entries will be either" */ int tree_entry_interesting(const struct name_entry *entry, - const struct strbuf *base, + struct strbuf *base, const struct pathspec *ps) { int i; int pathlen, baselen = base->len; - int never_interesting = -1; + int never_interesting = ps->has_wildcard ? 0 : -1; if (!ps->nr) { if (!ps->recursive || ps->max_depth == -1) @@ -578,7 +578,7 @@ int tree_entry_interesting(const struct name_entry *entry, if (baselen >= matchlen) { /* If it doesn't match, move along... */ if (!match_dir_prefix(base->buf, baselen, match, matchlen)) - continue; + goto match_wildcards; if (!ps->recursive || ps->max_depth == -1) return 2; @@ -596,6 +596,30 @@ int tree_entry_interesting(const struct name_entry *entry, &never_interesting)) return 1; } + +match_wildcards: + if (!ps->items[i].has_wildcard) + continue; + + /* + * Concatenate base and entry->path into one and do + * fnmatch() on it. + */ + + strbuf_add(base, entry->path, pathlen); + + if (!fnmatch(match, base->buf, 0)) { + strbuf_setlen(base, baselen); + return 1; + } + strbuf_setlen(base, baselen); + + /* + * Match all directories. We'll try to match files + * later on. + */ + if (ps->recursive && S_ISDIR(entry->mode)) + return 1; } return never_interesting; /* No matches */ } diff --git a/tree-walk.h b/tree-walk.h index f81c232b5a..6589ee27e4 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -60,6 +60,6 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru return info->pathlen + tree_entry_len(n->path, n->sha1); } -extern int tree_entry_interesting(const struct name_entry *, const struct strbuf *, const struct pathspec *ps); +extern int tree_entry_interesting(const struct name_entry *, struct strbuf *, const struct pathspec *ps); #endif -- cgit v1.3 From 61cf28204508c095a68e7a9cb6307ca2a27112c9 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Wed, 15 Dec 2010 22:02:48 +0700 Subject: pathspec: add match_pathspec_depth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit match_pathspec_depth() is a clone of match_pathspec() except that it can take depth limit. Computation is a bit lighter compared to match_pathspec() because it's usually precomputed and stored in struct pathspec. In long term, match_pathspec() and match_one() should be removed in favor of this function. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- dir.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dir.h | 3 +++ 2 files changed, 92 insertions(+) (limited to 'dir.c') diff --git a/dir.c b/dir.c index b6ccaf3703..168dad6152 100644 --- a/dir.c +++ b/dir.c @@ -199,6 +199,95 @@ int match_pathspec(const char **pathspec, const char *name, int namelen, return retval; } +/* + * Does 'match' match the given name? + * A match is found if + * + * (1) the 'match' string is leading directory of 'name', or + * (2) the 'match' string is a wildcard and matches 'name', or + * (3) the 'match' string is exactly the same as 'name'. + * + * and the return value tells which case it was. + * + * It returns 0 when there is no match. + */ +static int match_pathspec_item(const struct pathspec_item *item, int prefix, + const char *name, int namelen) +{ + /* name/namelen has prefix cut off by caller */ + const char *match = item->match + prefix; + int matchlen = item->len - prefix; + + /* If the match was just the prefix, we matched */ + if (!*match) + return MATCHED_RECURSIVELY; + + if (matchlen <= namelen && !strncmp(match, name, matchlen)) { + if (matchlen == namelen) + return MATCHED_EXACTLY; + + if (match[matchlen-1] == '/' || name[matchlen] == '/') + return MATCHED_RECURSIVELY; + } + + if (item->has_wildcard && !fnmatch(match, name, 0)) + return MATCHED_FNMATCH; + + return 0; +} + +/* + * Given a name and a list of pathspecs, see if the name matches + * any of the pathspecs. The caller is also interested in seeing + * all pathspec matches some names it calls this function with + * (otherwise the user could have mistyped the unmatched pathspec), + * and a mark is left in seen[] array for pathspec element that + * actually matched anything. + */ +int match_pathspec_depth(const struct pathspec *ps, + const char *name, int namelen, + int prefix, char *seen) +{ + int i, retval = 0; + + if (!ps->nr) { + if (!ps->recursive || ps->max_depth == -1) + return MATCHED_RECURSIVELY; + + if (within_depth(name, namelen, 0, ps->max_depth)) + return MATCHED_EXACTLY; + else + return 0; + } + + name += prefix; + namelen -= prefix; + + for (i = ps->nr - 1; i >= 0; i--) { + int how; + if (seen && seen[i] == MATCHED_EXACTLY) + continue; + how = match_pathspec_item(ps->items+i, prefix, name, namelen); + if (ps->recursive && ps->max_depth != -1 && + how && how != MATCHED_FNMATCH) { + int len = ps->items[i].len; + if (name[len] == '/') + len++; + if (within_depth(name+len, namelen-len, 0, ps->max_depth)) + how = MATCHED_EXACTLY; + else + how = 0; + } + if (how) { + if (retval < how) + retval = how; + if (seen && seen[i] < how) + seen[i] = how; + } + } + return retval; +} + static int no_wildcard(const char *string) { return string[strcspn(string, "*?[{\\")] == '\0'; diff --git a/dir.h b/dir.h index 5fa3fbe4c5..aa511da77b 100644 --- a/dir.h +++ b/dir.h @@ -65,6 +65,9 @@ struct dir_struct { #define MATCHED_FNMATCH 2 #define MATCHED_EXACTLY 3 extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen); +extern int match_pathspec_depth(const struct pathspec *pathspec, + const char *name, int namelen, + int prefix, char *seen); extern int within_depth(const char *name, int namelen, int depth, int max_depth); extern int fill_directory(struct dir_struct *dir, const char **pathspec); -- cgit v1.3 From e2a57aac8a8a2b786739a5a93ea9dcfd2f0fd0e2 Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Thu, 17 Mar 2011 12:26:46 +0100 Subject: Name make_*_path functions more accurately MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the make_*_path functions so it's clearer what they do, in particlar make clear what the differnce between make_absolute_path and make_nonrelative_path is by renaming them real_path and absolute_path respectively. make_relative_path has an understandable name and is renamed to relative_path to maintain the name convention. The function calls have been replaced 1-to-1 in their usage. Signed-off-by: Carlos Martín Nieto Signed-off-by: Junio C Hamano --- abspath.c | 18 ++++++++++++++++-- builtin/clone.c | 10 +++++----- builtin/init-db.c | 8 ++++---- builtin/receive-pack.c | 2 +- cache.h | 6 +++--- dir.c | 2 +- environment.c | 4 ++-- exec_cmd.c | 2 +- lockfile.c | 4 ++-- path.c | 2 +- setup.c | 14 +++++++------- t/t0000-basic.sh | 10 +++++----- test-path-utils.c | 4 ++-- wrapper.c | 4 ++-- 14 files changed, 52 insertions(+), 38 deletions(-) (limited to 'dir.c') diff --git a/abspath.c b/abspath.c index ff140689ed..3005aedde6 100644 --- a/abspath.c +++ b/abspath.c @@ -14,7 +14,14 @@ int is_directory(const char *path) /* We allow "recursive" symbolic links. Only within reason, though. */ #define MAXDEPTH 5 -const char *make_absolute_path(const char *path) +/* + * Use this to get the real path, i.e. resolve links. If you want an + * absolute path but don't mind links, use absolute_path. + * + * If path is our buffer, then return path, as it's already what the + * user wants. + */ +const char *real_path(const char *path) { static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1]; char cwd[1024] = ""; @@ -104,7 +111,14 @@ static const char *get_pwd_cwd(void) return cwd; } -const char *make_nonrelative_path(const char *path) +/* + * Use this to get an absolute path from a relative one. If you want + * to resolve links, you should use real_path. + * + * If the path is already absolute, then return path. As the user is + * never meant to free the return value, we're safe. + */ +const char *absolute_path(const char *path) { static char buf[PATH_MAX + 1]; diff --git a/builtin/clone.c b/builtin/clone.c index 2ee1fa9846..404f589680 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -100,7 +100,7 @@ static char *get_repo_path(const char *repo, int *is_bundle) path = mkpath("%s%s", repo, suffix[i]); if (is_directory(path)) { *is_bundle = 0; - return xstrdup(make_nonrelative_path(path)); + return xstrdup(absolute_path(path)); } } @@ -109,7 +109,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_nonrelative_path(path)); + return xstrdup(absolute_path(path)); } } @@ -203,7 +203,7 @@ static void setup_reference(const char *repo) struct transport *transport; const struct ref *extra; - ref_git = make_absolute_path(option_reference); + ref_git = real_path(option_reference); if (is_directory(mkpath("%s/.git/objects", ref_git))) ref_git = mkpath("%s/.git", ref_git); @@ -411,7 +411,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) path = get_repo_path(repo_name, &is_bundle); if (path) - repo = xstrdup(make_nonrelative_path(repo_name)); + repo = xstrdup(absolute_path(repo_name)); else if (!strchr(repo_name, ':')) die("repository '%s' does not exist", repo_name); else @@ -466,7 +466,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (safe_create_leading_directories_const(git_dir) < 0) die("could not create leading directories of '%s'", git_dir); - set_git_dir(make_absolute_path(git_dir)); + set_git_dir(real_path(git_dir)); if (0 <= option_verbosity) printf("Cloning into %s%s...\n", diff --git a/builtin/init-db.c b/builtin/init-db.c index fbeb380ee2..8f5cfd7122 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -501,7 +501,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) const char *git_dir_parent = strrchr(git_dir, '/'); if (git_dir_parent) { char *rel = xstrndup(git_dir, git_dir_parent - git_dir); - git_work_tree_cfg = xstrdup(make_absolute_path(rel)); + git_work_tree_cfg = xstrdup(real_path(rel)); free(rel); } if (!git_work_tree_cfg) { @@ -510,7 +510,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) die_errno ("Cannot access current working directory"); } if (work_tree) - set_git_work_tree(make_absolute_path(work_tree)); + set_git_work_tree(real_path(work_tree)); else set_git_work_tree(git_work_tree_cfg); if (access(get_git_work_tree(), X_OK)) @@ -519,10 +519,10 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) } else { if (work_tree) - set_git_work_tree(make_absolute_path(work_tree)); + set_git_work_tree(real_path(work_tree)); } - set_git_dir(make_absolute_path(git_dir)); + set_git_dir(real_path(git_dir)); return init_db(template_dir, flags); } diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 760817dbd7..d883585804 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -740,7 +740,7 @@ static int add_refs_from_alternate(struct alternate_object_database *e, void *un const struct ref *extra; e->name[-1] = '\0'; - other = xstrdup(make_absolute_path(e->base)); + other = xstrdup(real_path(e->base)); e->name[-1] = '/'; len = strlen(other); diff --git a/cache.h b/cache.h index cbdeaa1d0d..a99fd560e9 100644 --- a/cache.h +++ b/cache.h @@ -731,9 +731,9 @@ static inline int is_absolute_path(const char *path) return path[0] == '/' || has_dos_drive_prefix(path); } int is_directory(const char *); -const char *make_absolute_path(const char *path); -const char *make_nonrelative_path(const char *path); -const char *make_relative_path(const char *abs, const char *base); +const char *real_path(const char *path); +const char *absolute_path(const char *path); +const char *relative_path(const char *abs, const char *base); int normalize_path_copy(char *dst, const char *src); int longest_ancestor_length(const char *path, const char *prefix_list); char *strip_path_suffix(const char *path, const char *suffix); diff --git a/dir.c b/dir.c index 168dad6152..325fb56ad3 100644 --- a/dir.c +++ b/dir.c @@ -1128,7 +1128,7 @@ char *get_relative_cwd(char *buffer, int size, const char *dir) die_errno("can't find the current directory"); if (!is_absolute_path(dir)) - dir = make_absolute_path(dir); + dir = real_path(dir); while (*dir && *dir == *cwd) { dir++; diff --git a/environment.c b/environment.c index c3efbb9608..cc670b1562 100644 --- a/environment.c +++ b/environment.c @@ -139,7 +139,7 @@ static int git_work_tree_initialized; void set_git_work_tree(const char *new_work_tree) { if (git_work_tree_initialized) { - new_work_tree = make_absolute_path(new_work_tree); + new_work_tree = real_path(new_work_tree); if (strcmp(new_work_tree, work_tree)) die("internal error: work tree has already been set\n" "Current worktree: %s\nNew worktree: %s", @@ -147,7 +147,7 @@ void set_git_work_tree(const char *new_work_tree) return; } git_work_tree_initialized = 1; - work_tree = xstrdup(make_absolute_path(new_work_tree)); + work_tree = xstrdup(real_path(new_work_tree)); } const char *get_git_work_tree(void) diff --git a/exec_cmd.c b/exec_cmd.c index 38545e8bfd..171e841531 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -89,7 +89,7 @@ static void add_path(struct strbuf *out, const char *path) if (is_absolute_path(path)) strbuf_addstr(out, path); else - strbuf_addstr(out, make_nonrelative_path(path)); + strbuf_addstr(out, absolute_path(path)); strbuf_addch(out, PATH_SEP); } diff --git a/lockfile.c b/lockfile.c index b0d74cddde..c6fb77b26f 100644 --- a/lockfile.c +++ b/lockfile.c @@ -164,10 +164,10 @@ static char *unable_to_lock_message(const char *path, int err) "If no other git process is currently running, this probably means a\n" "git process crashed in this repository earlier. Make sure no other git\n" "process is running and remove the file manually to continue.", - make_nonrelative_path(path), strerror(err)); + absolute_path(path), strerror(err)); } else strbuf_addf(&buf, "Unable to create '%s.lock': %s", - make_nonrelative_path(path), strerror(err)); + absolute_path(path), strerror(err)); return strbuf_detach(&buf, NULL); } diff --git a/path.c b/path.c index 8951333cb8..4d73cc9cd2 100644 --- a/path.c +++ b/path.c @@ -397,7 +397,7 @@ int set_shared_perm(const char *path, int mode) return 0; } -const char *make_relative_path(const char *abs, const char *base) +const char *relative_path(const char *abs, const char *base) { static char buf[PATH_MAX + 1]; int i = 0, j = 0; diff --git a/setup.c b/setup.c index 021d0133ae..03cd84f2fc 100644 --- a/setup.c +++ b/setup.c @@ -9,7 +9,7 @@ char *prefix_path(const char *prefix, int len, const char *path) const char *orig = path; char *sanitized; if (is_absolute_path(orig)) { - const char *temp = make_absolute_path(path); + const char *temp = real_path(path); sanitized = xmalloc(len + strlen(temp) + 1); strcpy(sanitized, temp); } else { @@ -221,7 +221,7 @@ void setup_work_tree(void) work_tree = get_git_work_tree(); git_dir = get_git_dir(); if (!is_absolute_path(git_dir)) - git_dir = make_absolute_path(git_dir); + git_dir = real_path(get_git_dir()); if (!work_tree || chdir(work_tree)) die("This operation must be run in a work tree"); @@ -232,7 +232,7 @@ void setup_work_tree(void) if (getenv(GIT_WORK_TREE_ENVIRONMENT)) setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1); - set_git_dir(make_relative_path(git_dir, work_tree)); + set_git_dir(relative_path(git_dir, work_tree)); initialized = 1; } @@ -312,7 +312,7 @@ const char *read_gitfile_gently(const char *path) if (!is_git_directory(dir)) die("Not a git repository: %s", dir); - path = make_absolute_path(dir); + path = real_path(dir); free(buf); return path; @@ -392,7 +392,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, if (!prefixcmp(cwd, worktree) && cwd[strlen(worktree)] == '/') { /* cwd inside worktree */ - set_git_dir(make_absolute_path(gitdirenv)); + set_git_dir(real_path(gitdirenv)); if (chdir(worktree)) die_errno("Could not chdir to '%s'", worktree); cwd[len++] = '/'; @@ -417,7 +417,7 @@ static const char *setup_discovered_git_dir(const char *gitdir, /* --work-tree is set without --git-dir; use discovered one */ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) { if (offset != len && !is_absolute_path(gitdir)) - gitdir = xstrdup(make_absolute_path(gitdir)); + gitdir = xstrdup(real_path(gitdir)); if (chdir(cwd)) die_errno("Could not come back to cwd"); return setup_explicit_git_dir(gitdir, cwd, len, nongit_ok); @@ -425,7 +425,7 @@ static const char *setup_discovered_git_dir(const char *gitdir, /* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */ if (is_bare_repository_cfg > 0) { - set_git_dir(offset == len ? gitdir : make_absolute_path(gitdir)); + set_git_dir(offset == len ? gitdir : real_path(gitdir)); if (chdir(cwd)) die_errno("Could not come back to cwd"); return NULL; diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 8deec75c3a..f4e8f43bae 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -435,7 +435,7 @@ test_expect_success 'update-index D/F conflict' ' test $numpath0 = 1 ' -test_expect_success SYMLINKS 'absolute path works as expected' ' +test_expect_success SYMLINKS 'real path works as expected' ' mkdir first && ln -s ../.git first/.git && mkdir second && @@ -443,14 +443,14 @@ test_expect_success SYMLINKS 'absolute path works as expected' ' mkdir third && dir="$(cd .git; pwd -P)" && dir2=third/../second/other/.git && - test "$dir" = "$(test-path-utils make_absolute_path $dir2)" && + test "$dir" = "$(test-path-utils real_path $dir2)" && file="$dir"/index && - test "$file" = "$(test-path-utils make_absolute_path $dir2/index)" && + test "$file" = "$(test-path-utils real_path $dir2/index)" && basename=blub && - test "$dir/$basename" = "$(cd .git && test-path-utils make_absolute_path "$basename")" && + test "$dir/$basename" = "$(cd .git && test-path-utils real_path "$basename")" && ln -s ../first/file .git/syml && sym="$(cd first; pwd -P)"/file && - test "$sym" = "$(test-path-utils make_absolute_path "$dir2/syml")" + test "$sym" = "$(test-path-utils real_path "$dir2/syml")" ' test_expect_success 'very long name in the index handled sanely' ' diff --git a/test-path-utils.c b/test-path-utils.c index d261398d6c..e7671593df 100644 --- a/test-path-utils.c +++ b/test-path-utils.c @@ -11,9 +11,9 @@ int main(int argc, char **argv) return 0; } - if (argc >= 2 && !strcmp(argv[1], "make_absolute_path")) { + if (argc >= 2 && !strcmp(argv[1], "real_path")) { while (argc > 2) { - puts(make_absolute_path(argv[2])); + puts(real_path(argv[2])); argc--; argv++; } diff --git a/wrapper.c b/wrapper.c index 4c147d6c48..28290002b9 100644 --- a/wrapper.c +++ b/wrapper.c @@ -209,7 +209,7 @@ int xmkstemp(char *template) if (!template[0]) template = origtemplate; - nonrelative_template = make_nonrelative_path(template); + nonrelative_template = absolute_path(template); errno = saved_errno; die_errno("Unable to create temporary file '%s'", nonrelative_template); @@ -344,7 +344,7 @@ int xmkstemp_mode(char *template, int mode) if (!template[0]) template = origtemplate; - nonrelative_template = make_nonrelative_path(template); + nonrelative_template = absolute_path(template); errno = saved_errno; die_errno("Unable to create temporary file '%s'", nonrelative_template); -- cgit v1.3