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 pclo...@gmail.com
---
builtin/clean.c | 2 +-
builtin/ls-files.c | 5 +++--
dir.c| 4 ++--
dir.h| 10 +++---
rerere.c | 2 +-
t/t4010-diff-pathspec.sh | 17 +
6 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/builtin/clean.c b/builtin/clean.c
index f59c753..4c9680a 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 02db0e1..47c3880 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 7b50072..2fd0ebd 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 c31ed9a..55e5345 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,
+