summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Nguyễn Thái Ngọc Duy <pclouds@gmail.com>2014-01-24 20:40:33 +0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2014-02-24 14:37:19 -0800
commitae8d0824217bdf97c69ead49568cd03fc140627b (patch)
treec188d3275e08dd074476d03a8656981dbd5ef643
parentmatch_pathspec: match pathspec "foo/" against directory "foo" (diff)
downloadtgif-ae8d0824217bdf97c69ead49568cd03fc140627b.tar.xz
pathspec: pass directory indicator to match_pathspec_item()
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 <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/clean.c2
-rw-r--r--builtin/ls-files.c5
-rw-r--r--dir.c4
-rw-r--r--dir.h10
-rw-r--r--rerere.c2
-rwxr-xr-xt/t4010-diff-pathspec.sh6
6 files changed, 20 insertions, 9 deletions
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