From 6f525e7100061fb0dbc2d9230cc9948c7c5b2978 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Sun, 6 Jan 2013 16:58:08 +0000 Subject: add.c: move pathspec matchers into new pathspec.c for reuse Extract the following functions from builtin/add.c to pathspec.c, in preparation for reuse by a new git check-ignore command: - fill_pathspec_matches() - find_used_pathspec() The functions being extracted are not changed in any way, except removal of the 'static' qualifier. Also add comments documenting these newly public functions, including clarifications that they operate on the index. Signed-off-by: Adam Spiers Signed-off-by: Junio C Hamano --- pathspec.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 pathspec.c (limited to 'pathspec.c') diff --git a/pathspec.c b/pathspec.c new file mode 100644 index 0000000000..1472af89ce --- /dev/null +++ b/pathspec.c @@ -0,0 +1,57 @@ +#include "cache.h" +#include "dir.h" +#include "pathspec.h" + +/* + * Finds which of the given pathspecs match items in the index. + * + * For each pathspec, sets the corresponding entry in the seen[] array + * (which should be specs items long, i.e. the same size as pathspec) + * to the nature of the "closest" (i.e. most specific) match found for + * that pathspec in the index, if it was a closer type of match than + * the existing entry. As an optimization, matching is skipped + * altogether if seen[] already only contains non-zero entries. + * + * If seen[] has not already been written to, it may make sense + * to use find_used_pathspec() instead. + */ +void fill_pathspec_matches(const char **pathspec, char *seen, int specs) +{ + int num_unmatched = 0, i; + + /* + * Since we are walking the index as if we were walking the directory, + * we have to mark the matched pathspec as seen; otherwise we will + * mistakenly think that the user gave a pathspec that did not match + * anything. + */ + for (i = 0; i < specs; i++) + if (!seen[i]) + num_unmatched++; + if (!num_unmatched) + return; + for (i = 0; i < active_nr; i++) { + struct cache_entry *ce = active_cache[i]; + match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen); + } +} + +/* + * Finds which of the given pathspecs match items in the index. + * + * This is a one-shot wrapper around fill_pathspec_matches() which + * allocates, populates, and returns a seen[] array indicating the + * nature of the "closest" (i.e. most specific) matches which each of + * the given pathspecs achieves against all items in the index. + */ +char *find_used_pathspec(const char **pathspec) +{ + char *seen; + int i; + + for (i = 0; pathspec[i]; i++) + ; /* just counting */ + seen = xcalloc(i, 1); + fill_pathspec_matches(pathspec, seen, i); + return seen; +} -- cgit v1.2.1 From 4b78d7bccdda25290ab6c04bf45d835b4fdfab45 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Sun, 6 Jan 2013 16:58:09 +0000 Subject: pathspec.c: rename newly public functions for clarity Perform the following function renames to make it explicit that these pathspec handling functions are for matching against the index, rather than against a tree or the working directory. - fill_pathspec_matches() -> add_pathspec_matches_against_index() - find_used_pathspec() -> find_pathspecs_matching_against_index() Signed-off-by: Adam Spiers Signed-off-by: Junio C Hamano --- pathspec.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'pathspec.c') diff --git a/pathspec.c b/pathspec.c index 1472af89ce..b73b15cbb3 100644 --- a/pathspec.c +++ b/pathspec.c @@ -13,9 +13,10 @@ * altogether if seen[] already only contains non-zero entries. * * If seen[] has not already been written to, it may make sense - * to use find_used_pathspec() instead. + * to use find_pathspecs_matching_against_index() instead. */ -void fill_pathspec_matches(const char **pathspec, char *seen, int specs) +void add_pathspec_matches_against_index(const char **pathspec, + char *seen, int specs) { int num_unmatched = 0, i; @@ -39,12 +40,12 @@ void fill_pathspec_matches(const char **pathspec, char *seen, int specs) /* * Finds which of the given pathspecs match items in the index. * - * This is a one-shot wrapper around fill_pathspec_matches() which - * allocates, populates, and returns a seen[] array indicating the - * nature of the "closest" (i.e. most specific) matches which each of - * the given pathspecs achieves against all items in the index. + * This is a one-shot wrapper around add_pathspec_matches_against_index() + * which allocates, populates, and returns a seen[] array indicating the + * nature of the "closest" (i.e. most specific) matches which each of the + * given pathspecs achieves against all items in the index. */ -char *find_used_pathspec(const char **pathspec) +char *find_pathspecs_matching_against_index(const char **pathspec) { char *seen; int i; @@ -52,6 +53,6 @@ char *find_used_pathspec(const char **pathspec) for (i = 0; pathspec[i]; i++) ; /* just counting */ seen = xcalloc(i, 1); - fill_pathspec_matches(pathspec, seen, i); + add_pathspec_matches_against_index(pathspec, seen, i); return seen; } -- cgit v1.2.1 From 9d67b61f739a1a898bc8c9960047ebff0e9c9d09 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Sun, 6 Jan 2013 16:58:10 +0000 Subject: add.c: extract check_path_for_gitlink() from treat_gitlinks() for reuse Extract the body of the for loop in treat_gitlinks() into a separate check_path_for_gitlink() function so that it can be reused elsewhere. This paves the way for a new check-ignore sub-command. Also document treat_gitlinks(). Signed-off-by: Adam Spiers Signed-off-by: Junio C Hamano --- pathspec.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'pathspec.c') diff --git a/pathspec.c b/pathspec.c index b73b15cbb3..02d3344460 100644 --- a/pathspec.c +++ b/pathspec.c @@ -56,3 +56,34 @@ char *find_pathspecs_matching_against_index(const char **pathspec) add_pathspec_matches_against_index(pathspec, seen, i); return seen; } + +/* + * Check the index to see whether path refers to a submodule, or + * something inside a submodule. If the former, returns the path with + * any trailing slash stripped. If the latter, dies with an error + * message. + */ +const char *check_path_for_gitlink(const char *path) +{ + int i, path_len = strlen(path); + for (i = 0; i < active_nr; i++) { + struct cache_entry *ce = active_cache[i]; + if (S_ISGITLINK(ce->ce_mode)) { + int ce_len = ce_namelen(ce); + if (path_len <= ce_len || path[ce_len] != '/' || + memcmp(ce->name, path, ce_len)) + /* path does not refer to this + * submodule or anything inside it */ + continue; + if (path_len == ce_len + 1) { + /* path refers to submodule; + * strip trailing slash */ + return xstrndup(ce->name, ce_len); + } else { + die (_("Path '%s' is in submodule '%.*s'"), + path, ce_len, ce->name); + } + } + } + return path; +} -- cgit v1.2.1 From 512aaf9453cecfa57dddc61aec2132b936b2ff70 Mon Sep 17 00:00:00 2001 From: Adam Spiers Date: Sun, 6 Jan 2013 16:58:11 +0000 Subject: add.c: extract new die_if_path_beyond_symlink() for reuse This will be reused by a new git check-ignore command. Also document validate_pathspec(). Signed-off-by: Adam Spiers Signed-off-by: Junio C Hamano --- pathspec.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'pathspec.c') diff --git a/pathspec.c b/pathspec.c index 02d3344460..284f3970a3 100644 --- a/pathspec.c +++ b/pathspec.c @@ -87,3 +87,15 @@ const char *check_path_for_gitlink(const char *path) } return path; } + +/* + * Dies if the given path refers to a file inside a symlinked + * directory in the index. + */ +void die_if_path_beyond_symlink(const char *path, const char *prefix) +{ + if (has_symlink_leading_path(path, strlen(path))) { + int len = prefix ? strlen(prefix) : 0; + die(_("'%s' is beyond a symbolic link"), path + len); + } +} -- cgit v1.2.1