From ebb32893bad46bf5edae881552672a47dd2684b8 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Fri, 24 Jan 2014 20:40:29 +0700 Subject: pathspec: convert some match_pathspec_depth() to dir_path_match() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helps reduce the number of match_pathspec_depth() call sites and show how m_p_d() is used. And it usage is: - match against an index entry (ce_path_match or match_pathspec_depth in ls-files) - match against a dir_entry from read_directory (dir_path_match and match_pathspec_depth in clean.c, which will be converted later) - resolve-undo (rerere.c and ls-files.c) Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/ls-files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/ls-files.c') diff --git a/builtin/ls-files.c b/builtin/ls-files.c index e1cf6d8547..e238608bda 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -64,7 +64,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) if (len >= ent->len) die("git ls-files: internal error - directory entry not superset of prefix"); - if (!match_pathspec_depth(&pathspec, ent->name, ent->len, len, ps_matched)) + if (!dir_path_match(ent, &pathspec, len, ps_matched)) return; fputs(tag, stdout); -- cgit v1.2.3 From 854b09592ce9a497f56f35d973c4abe43af84cd1 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Fri, 24 Jan 2014 20:40:30 +0700 Subject: pathspec: rename match_pathspec_depth() to match_pathspec() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A long time ago, for some reason I was not happy with match_pathspec(). I created a better version, match_pathspec_depth() that was suppose to replace match_pathspec() eventually. match_pathspec() has finally been gone since 6 months ago. Use the shorter name for match_pathspec_depth(). Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/clean.c | 4 ++-- builtin/ls-files.c | 6 ++++-- builtin/ls-tree.c | 2 +- dir.c | 20 ++++++++++---------- dir.h | 10 +++++----- rerere.c | 4 ++-- t/t6131-pathspec-icase.sh | 6 +++--- 7 files changed, 27 insertions(+), 25 deletions(-) (limited to 'builtin/ls-files.c') diff --git a/builtin/clean.c b/builtin/clean.c index 2f26297142..f59c753a46 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -961,8 +961,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix) die_errno("Cannot lstat '%s'", ent->name); if (pathspec.nr) - matches = match_pathspec_depth(&pathspec, ent->name, - len, 0, NULL); + matches = match_pathspec(&pathspec, ent->name, + len, 0, NULL); if (S_ISDIR(st.st_mode)) { if (remove_directories || (matches == MATCHED_EXACTLY)) { diff --git a/builtin/ls-files.c b/builtin/ls-files.c index e238608bda..02db0e1ae8 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -139,7 +139,8 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce) if (len >= ce_namelen(ce)) die("git ls-files: internal error - cache entry not superset of prefix"); - if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), len, ps_matched)) + if (!match_pathspec(&pathspec, ce->name, ce_namelen(ce), + len, ps_matched)) return; if (tag && *tag && show_valid_bit && @@ -195,7 +196,8 @@ static void show_ru_info(void) len = strlen(path); if (len < max_prefix_len) continue; /* outside of the prefix */ - if (!match_pathspec_depth(&pathspec, path, len, max_prefix_len, ps_matched)) + if (!match_pathspec(&pathspec, path, len, + max_prefix_len, ps_matched)) continue; /* uninterested */ for (i = 0; i < 3; i++) { if (!ui->mode[i]) diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 65ec931846..51184dfa2e 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -171,7 +171,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) * show_recursive() rolls its own matching code and is * generally ignorant of 'struct pathspec'. The magic mask * cannot be lifted until it is converted to use - * match_pathspec_depth() or tree_entry_interesting() + * match_pathspec() or tree_entry_interesting() */ parse_pathspec(&pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE, PATHSPEC_PREFER_CWD, diff --git a/dir.c b/dir.c index b35b6330f8..442a548f25 100644 --- a/dir.c +++ b/dir.c @@ -218,7 +218,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, * The normal call pattern is: * 1. prefix = common_prefix_len(ps); * 2. prune something, or fill_directory - * 3. match_pathspec_depth() + * 3. match_pathspec() * * 'prefix' at #1 may be shorter than the command's prefix and * it's ok for #2 to match extra files. Those extras will be @@ -282,10 +282,10 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix, * pathspec did not match any names, which could indicate that the * user mistyped the nth pathspec. */ -static int match_pathspec_depth_1(const struct pathspec *ps, - const char *name, int namelen, - int prefix, char *seen, - int exclude) +static int do_match_pathspec(const struct pathspec *ps, + const char *name, int namelen, + int prefix, char *seen, + int exclude) { int i, retval = 0; @@ -350,15 +350,15 @@ static int match_pathspec_depth_1(const struct pathspec *ps, return retval; } -int match_pathspec_depth(const struct pathspec *ps, - const char *name, int namelen, - int prefix, char *seen) +int match_pathspec(const struct pathspec *ps, + const char *name, int namelen, + int prefix, char *seen) { int positive, negative; - positive = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 0); + positive = do_match_pathspec(ps, name, namelen, prefix, seen, 0); if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive) return positive; - negative = match_pathspec_depth_1(ps, name, namelen, prefix, seen, 1); + negative = do_match_pathspec(ps, name, namelen, prefix, seen, 1); return negative ? 0 : positive; } diff --git a/dir.h b/dir.h index 65f54b606f..c31ed9af78 100644 --- a/dir.h +++ b/dir.h @@ -132,9 +132,9 @@ struct dir_struct { extern int simple_length(const char *match); extern int no_wildcard(const char *string); extern char *common_prefix(const struct pathspec *pathspec); -extern int match_pathspec_depth(const struct pathspec *pathspec, - const char *name, int namelen, - int prefix, char *seen); +extern int match_pathspec(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 struct pathspec *pathspec); @@ -209,14 +209,14 @@ static inline int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec, char *seen) { - return match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen); + return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen); } static inline int dir_path_match(const struct dir_entry *ent, const struct pathspec *pathspec, int prefix, char *seen) { - return match_pathspec_depth(pathspec, ent->name, ent->len, prefix, seen); + return match_pathspec(pathspec, ent->name, ent->len, prefix, seen); } #endif diff --git a/rerere.c b/rerere.c index 1f2d21a72f..34a21c431b 100644 --- a/rerere.c +++ b/rerere.c @@ -672,8 +672,8 @@ int rerere_forget(struct pathspec *pathspec) find_conflict(&conflict); for (i = 0; i < conflict.nr; i++) { struct string_list_item *it = &conflict.items[i]; - if (!match_pathspec_depth(pathspec, it->string, strlen(it->string), - 0, NULL)) + if (!match_pathspec(pathspec, it->string, + strlen(it->string), 0, NULL)) continue; rerere_forget_one_path(it->string, &merge_rr); } diff --git a/t/t6131-pathspec-icase.sh b/t/t6131-pathspec-icase.sh index a7c7ff5f49..39fc3f6769 100755 --- a/t/t6131-pathspec-icase.sh +++ b/t/t6131-pathspec-icase.sh @@ -69,7 +69,7 @@ test_expect_success 'tree_entry_interesting matches :(icase)bar with empty prefi test_cmp expect actual ' -test_expect_success 'match_pathspec_depth matches :(icase)bar' ' +test_expect_success 'match_pathspec matches :(icase)bar' ' cat <<-EOF >expect && BAR bAr @@ -79,7 +79,7 @@ test_expect_success 'match_pathspec_depth matches :(icase)bar' ' test_cmp expect actual ' -test_expect_success 'match_pathspec_depth matches :(icase)bar with prefix' ' +test_expect_success 'match_pathspec matches :(icase)bar with prefix' ' cat <<-EOF >expect && fOo/BAR fOo/bAr @@ -89,7 +89,7 @@ test_expect_success 'match_pathspec_depth matches :(icase)bar with prefix' ' test_cmp expect actual ' -test_expect_success 'match_pathspec_depth matches :(icase)bar with empty prefix' ' +test_expect_success 'match_pathspec matches :(icase)bar with empty prefix' ' cat <<-EOF >expect && bar fOo/BAR -- cgit v1.2.3 From ae8d0824217bdf97c69ead49568cd03fc140627b Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Fri, 24 Jan 2014 20:40:33 +0700 Subject: pathspec: pass directory indicator to match_pathspec_item() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch activates the DO_MATCH_DIRECTORY code in m_p_i(), which makes "git diff HEAD submodule/" and "git diff HEAD submodule" produce the same output. Previously only the version without trailing slash returns the difference (if any). That's the effect of new ce_path_match(). dir_path_match() is not executed by the new tests. And it should not introduce regressions. Previously if path "dir/" is passed in with pathspec "dir/", they obviously match. With new dir_path_match(), the path becomes _directory_ "dir" vs pathspec "dir/", which is not executed by the old code path in m_p_i(). The new code path is executed and produces the same result. The other case is pathspec "dir" and path "dir/" is now turned to "dir" (with DO_MATCH_DIRECTORY). Still the same result before or after the patch. So why change? Because of the next patch about clean.c. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/clean.c | 2 +- builtin/ls-files.c | 5 +++-- dir.c | 4 ++-- dir.h | 10 +++++++--- rerere.c | 2 +- t/t4010-diff-pathspec.sh | 6 ++++++ 6 files changed, 20 insertions(+), 9 deletions(-) (limited to 'builtin/ls-files.c') diff --git a/builtin/clean.c b/builtin/clean.c index f59c753a46..4c9680acb6 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -962,7 +962,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) if (pathspec.nr) matches = match_pathspec(&pathspec, ent->name, - len, 0, NULL); + len, 0, NULL, 0); if (S_ISDIR(st.st_mode)) { if (remove_directories || (matches == MATCHED_EXACTLY)) { diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 02db0e1ae8..47c38808a2 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -140,7 +140,8 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce) die("git ls-files: internal error - cache entry not superset of prefix"); if (!match_pathspec(&pathspec, ce->name, ce_namelen(ce), - len, ps_matched)) + len, ps_matched, + S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode))) return; if (tag && *tag && show_valid_bit && @@ -197,7 +198,7 @@ static void show_ru_info(void) if (len < max_prefix_len) continue; /* outside of the prefix */ if (!match_pathspec(&pathspec, path, len, - max_prefix_len, ps_matched)) + max_prefix_len, ps_matched, 0)) continue; /* uninterested */ for (i = 0; i < 3; i++) { if (!ui->mode[i]) diff --git a/dir.c b/dir.c index 5359d75e8b..98bb50fbab 100644 --- a/dir.c +++ b/dir.c @@ -360,10 +360,10 @@ static int do_match_pathspec(const struct pathspec *ps, int match_pathspec(const struct pathspec *ps, const char *name, int namelen, - int prefix, char *seen) + int prefix, char *seen, int is_dir) { int positive, negative; - unsigned flags = 0; + unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0; positive = do_match_pathspec(ps, name, namelen, prefix, seen, flags); if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive) diff --git a/dir.h b/dir.h index c31ed9af78..55e53456af 100644 --- a/dir.h +++ b/dir.h @@ -134,7 +134,7 @@ extern int no_wildcard(const char *string); extern char *common_prefix(const struct pathspec *pathspec); extern int match_pathspec(const struct pathspec *pathspec, const char *name, int namelen, - int prefix, char *seen); + int prefix, char *seen, int is_dir); extern int within_depth(const char *name, int namelen, int depth, int max_depth); extern int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec); @@ -209,14 +209,18 @@ static inline int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec, char *seen) { - return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen); + return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen, + S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode)); } static inline int dir_path_match(const struct dir_entry *ent, const struct pathspec *pathspec, int prefix, char *seen) { - return match_pathspec(pathspec, ent->name, ent->len, prefix, seen); + int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/'; + int len = has_trailing_dir ? ent->len - 1 : ent->len; + return match_pathspec(pathspec, ent->name, len, prefix, seen, + has_trailing_dir); } #endif diff --git a/rerere.c b/rerere.c index 34a21c431b..d55aa8a01b 100644 --- a/rerere.c +++ b/rerere.c @@ -673,7 +673,7 @@ int rerere_forget(struct pathspec *pathspec) for (i = 0; i < conflict.nr; i++) { struct string_list_item *it = &conflict.items[i]; if (!match_pathspec(pathspec, it->string, - strlen(it->string), 0, NULL)) + strlen(it->string), 0, NULL, 0)) continue; rerere_forget_one_path(it->string, &merge_rr); } diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index 15a491295e..d30ff34be7 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -127,4 +127,10 @@ test_expect_success 'diff-tree ignores trailing slash on submodule path' ' test_cmp expect actual ' +test_expect_success 'diff-cache ignores trailing slash on submodule path' ' + git diff --name-only HEAD^ submod >expect && + git diff --name-only HEAD^ submod/ >actual && + test_cmp expect actual +' + test_done -- cgit v1.2.3