This function is as same as get_pathspec_old() except that it produces struct pathspec directly. no_prefix code path is necessary because init_pathspec() can be called without get_pathspec_old() in "diff --no-index" case. Without this exception, prefix_path() will be eventually called and die because there is not worktree. --- cache.h | 1 + dir.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/cache.h b/cache.h index 08b4633..de57dff 100644 --- a/cache.h +++ b/cache.h @@ -534,6 +534,7 @@ struct pathspec { }; extern int init_pathspec(struct pathspec *, const char **); +extern int get_pathspec(struct pathspec *, const char *, int, const char **); extern void free_pathspec(struct pathspec *); extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec); extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path, int format_check); diff --git a/dir.c b/dir.c index 58cedd3..64348a1 100644 --- a/dir.c +++ b/dir.c @@ -1265,33 +1265,59 @@ static int pathspec_item_cmp(const void *a_, const void *b_) return strcmp(a->match, b->match); } -int init_pathspec(struct pathspec *pathspec, const char **paths) +extern int prefix_pathspec(struct pathspec_item *item, const char *prefix, + int prefixlen, const char *elt); +const char *no_prefix = "We do not want outside repository check."; +int get_pathspec(struct pathspec *pathspec, const char *prefix, + int argc, const char **argv) { - const char **p = paths; - int i; + struct pathspec_item *pitem; + const char **dst; + int prefixlen; memset(pathspec, 0, sizeof(*pathspec)); - if (!p) + + if ((!prefix || prefix == no_prefix) && !argc) return 0; - while (*p) - p++; - pathspec->raw = paths; - pathspec->nr = p - paths; - if (!pathspec->nr) + + if (!argc) { + static const char *spec[2]; + spec[0] = prefix; + spec[1] = NULL; + init_pathspec(pathspec, spec); + pathspec->items[0].plain_len = pathspec->items[0].len; return 0; + } - pathspec->items = xmalloc(sizeof(struct pathspec_item)*pathspec->nr); - memset(pathspec->items, 0, 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]; + if (!strcmp(*argv, ":")) + return 0; - item->match = path; - item->len = strlen(path); - if (no_wildcard(path)) - item->magic |= PATHSPEC_NOGLOB; + prefixlen = prefix && prefix != no_prefix ? strlen(prefix) : 0; + pathspec->nr = argc; /* be optimistic, lower it later if necessary */ + pathspec->items = xmalloc(sizeof(struct pathspec_item) * argc); + pathspec->raw = argv; + pitem = pathspec->items; + dst = argv; + + while (*argv) { + if (prefix == no_prefix) { + memset(pitem, 0, sizeof(*pitem)); + pitem->match = *argv; + pitem->len = strlen(pitem->match); + } + else + prefix_pathspec(pitem, prefix, prefixlen, *argv); + *dst = *argv++; + if (pitem->match) { + if (no_wildcard(pitem->match + pitem->plain_len)) + pitem->magic |= PATHSPEC_NOGLOB; + else + pathspec->use_wildcard = 1; + pitem++; + dst++; + } else - pathspec->use_wildcard = 1; + pathspec->nr--; } qsort(pathspec->items, pathspec->nr, @@ -1300,6 +1326,16 @@ int init_pathspec(struct pathspec *pathspec, const char **paths) return 0; } +int init_pathspec(struct pathspec *pathspec, const char **paths) +{ + const char **p = paths; + + while (p && *p) + p++; + + return get_pathspec(pathspec, no_prefix, p - paths, paths); +} + void free_pathspec(struct pathspec *pathspec) { free(pathspec->items); -- 1.7.4.74.g639db -- 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