* [PATCH 0/5] Globbing support in diff family
@ 2010-09-19 23:29 Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 1/5] pathspec: mark wildcard pathspecs from the beginning Nguyễn Thái Ngọc Duy
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2010-09-19 23:29 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
This is on top of the pathspec struct series
http://mid.gmane.org/1284938514-16663-1-git-send-email-pclouds@gmail.com
One question to document experts: where to document "pathspec", git.txt?
Nguyễn Thái Ngọc Duy (5):
pathspec: mark wildcard pathspecs from the beginning
pathspec: add tree_recursive_diff parameter
tree_entry_interesting: turn to match_pathspec if wildcard is present
Convert ce_path_match() to use struct pathspec
ce_path_match: drop prefix matching in favor of match_pathspec
builtin/update-index.c | 8 ++++++--
cache.h | 5 ++++-
diff-lib.c | 10 ++++++++--
dir.c | 7 ++++++-
preload-index.c | 5 ++++-
read-cache.c | 25 ++-----------------------
revision.c | 5 ++++-
t/t4010-diff-pathspec.sh | 23 +++++++++++++++++++++++
tree-diff.c | 1 +
tree-walk.c | 18 ++++++++++++++++++
wt-status.c | 5 ++++-
11 files changed, 80 insertions(+), 32 deletions(-)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/5] pathspec: mark wildcard pathspecs from the beginning
2010-09-19 23:29 [PATCH 0/5] Globbing support in diff family Nguyễn Thái Ngọc Duy
@ 2010-09-19 23:29 ` Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 2/5] pathspec: add tree_recursive_diff parameter Nguyễn Thái Ngọc Duy
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2010-09-19 23:29 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
match_pathspec() should be converted to use this as well. Not now
though.
cache.h | 2 ++
dir.c | 7 ++++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/cache.h b/cache.h
index 045c9fc..7a3e0a0 100644
--- a/cache.h
+++ b/cache.h
@@ -495,8 +495,10 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
struct pathspec {
const char **raw;
int nr;
+ int has_wildcard:1;
struct pathspec_item {
int len;
+ int has_wildcard:1;
} *items;
};
diff --git a/dir.c b/dir.c
index 80b2df2..a44c7b3 100644
--- a/dir.c
+++ b/dir.c
@@ -1088,7 +1088,12 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)
pathspec->items = xmalloc(sizeof(struct pathspec_item)*pathspec->nr);
for (i = 0; i < pathspec->nr; i++) {
- pathspec->items[i].len = strlen(paths[i]);
+ struct pathspec_item *item = pathspec->items+i;
+
+ item->len = strlen(paths[i]);
+ item->has_wildcard = !no_wildcard(paths[i]);
+ if (item->has_wildcard)
+ pathspec->has_wildcard = 1;
}
return 0;
}
--
1.7.1.rc1.70.g788ca
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/5] pathspec: add tree_recursive_diff parameter
2010-09-19 23:29 [PATCH 0/5] Globbing support in diff family Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 1/5] pathspec: mark wildcard pathspecs from the beginning Nguyễn Thái Ngọc Duy
@ 2010-09-19 23:29 ` Nguyễn Thái Ngọc Duy
2010-09-27 22:20 ` Junio C Hamano
2010-09-19 23:29 ` [PATCH 3/5] tree_entry_interesting: turn to match_pathspec if wildcard is present Nguyễn Thái Ngọc Duy
` (2 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2010-09-19 23:29 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
When wildcard match is implemented, a full path is needed to do final
match. What type of diff_tree is performed determines how to treat
directories:
- If it's recursive diff, directories are just an intermediate step.
All path must end with a file name. Thus, directories will be
unconditionally matched.
- If it's non-recursive, directories are treated like files and is
matched against pathspect as full path.
Strictly speaking, this should be a new parameter to
tree_entry_interesting(). But I don't feel like chaning
tree_entry_interesting() too often.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
cache.h | 1 +
tree-diff.c | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/cache.h b/cache.h
index 7a3e0a0..dc54d16 100644
--- a/cache.h
+++ b/cache.h
@@ -496,6 +496,7 @@ struct pathspec {
const char **raw;
int nr;
int has_wildcard:1;
+ int tree_recursive_diff:1;
struct pathspec_item {
int len;
int has_wildcard:1;
diff --git a/tree-diff.c b/tree-diff.c
index 50d7e6d..7e58f54 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -170,6 +170,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru
{
int baselen = strlen(base);
+ opt->pathspec.tree_recursive_diff = DIFF_OPT_TST(opt, RECURSIVE);
for (;;) {
if (DIFF_OPT_TST(opt, QUICK) &&
DIFF_OPT_TST(opt, HAS_CHANGES))
--
1.7.1.rc1.70.g788ca
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/5] tree_entry_interesting: turn to match_pathspec if wildcard is present
2010-09-19 23:29 [PATCH 0/5] Globbing support in diff family Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 1/5] pathspec: mark wildcard pathspecs from the beginning Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 2/5] pathspec: add tree_recursive_diff parameter Nguyễn Thái Ngọc Duy
@ 2010-09-19 23:29 ` Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 4/5] Convert ce_path_match() to use struct pathspec Nguyễn Thái Ngọc Duy
2010-09-19 23:30 ` [PATCH 5/5] ce_path_match: drop prefix matching in favor of match_pathspec Nguyễn Thái Ngọc Duy
4 siblings, 0 replies; 9+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2010-09-19 23:29 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
A pathspec with wildcard usually requires full path to do
matching. When full path is found, match_pathspec() can do the job
pretty well (actually it can utilize pathspec_item.has_wildcard, but
that's another matter).
So if tree_entry_interesting() finds that there is wildcard in any
pathspec, it just skips all of its optimizations, tries to make full
path and pass to match_pathspec().
The implementation is pretty naive. Maybe with some pattern analysis,
we can do some early tree cutting.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
t/t4010-diff-pathspec.sh | 14 ++++++++++++++
tree-walk.c | 18 ++++++++++++++++++
2 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
index 94df7ae..4b120f8 100755
--- a/t/t4010-diff-pathspec.sh
+++ b/t/t4010-diff-pathspec.sh
@@ -70,4 +70,18 @@ test_expect_success 'diff-tree pathspec' '
test_cmp expected current
'
+EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+
+test_expect_success 'diff-tree with wildcard shows dir also matches' '
+ git diff-tree --name-only $EMPTY_TREE $tree -- "f*" >result &&
+ echo file0 >expected &&
+ test_cmp expected result
+'
+
+test_expect_success 'diff-tree -r with wildcard' '
+ git diff-tree -r --name-only $EMPTY_TREE $tree -- "*file1" >result &&
+ echo path1/file1 >expected &&
+ test_cmp expected result
+'
+
test_done
diff --git a/tree-walk.c b/tree-walk.c
index 01168ea..bc8c9bd 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -2,6 +2,7 @@
#include "tree-walk.h"
#include "unpack-trees.h"
#include "tree.h"
+#include "dir.h"
static const char *get_mode(const char *str, unsigned int *modep)
{
@@ -478,6 +479,23 @@ int tree_entry_interesting(const struct name_entry *entry,
pathlen = tree_entry_len(entry->path, entry->sha1);
+ if (ps->has_wildcard) {
+ static char full_path[PATH_MAX];
+
+ /*
+ * If it's recursive diff, directories are
+ * intermediate step before ending up to a file.
+ * Let it pass and we can match the files within
+ * later.
+ */
+ if (ps->tree_recursive_diff && S_ISDIR(entry->mode))
+ return 1;
+
+ memcpy(full_path, base, baselen);
+ memcpy(full_path+baselen, entry->path, pathlen+1);
+ return match_pathspec(ps->raw, full_path, baselen+pathlen, 0, NULL) > 0;
+ }
+
for (i = 0; i < ps->nr; i++) {
const char *match = ps->raw[i];
int matchlen = ps->items[i].len;
--
1.7.1.rc1.70.g788ca
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/5] Convert ce_path_match() to use struct pathspec
2010-09-19 23:29 [PATCH 0/5] Globbing support in diff family Nguyễn Thái Ngọc Duy
` (2 preceding siblings ...)
2010-09-19 23:29 ` [PATCH 3/5] tree_entry_interesting: turn to match_pathspec if wildcard is present Nguyễn Thái Ngọc Duy
@ 2010-09-19 23:29 ` Nguyễn Thái Ngọc Duy
2010-09-19 23:30 ` [PATCH 5/5] ce_path_match: drop prefix matching in favor of match_pathspec Nguyễn Thái Ngọc Duy
4 siblings, 0 replies; 9+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2010-09-19 23:29 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/update-index.c | 8 ++++++--
cache.h | 2 +-
diff-lib.c | 10 ++++++++--
preload-index.c | 5 ++++-
read-cache.c | 8 +++++---
revision.c | 5 ++++-
wt-status.c | 5 ++++-
7 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 3ab214d..9d1f67e 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -543,7 +543,10 @@ static int do_reupdate(int ac, const char **av,
*/
int pos;
int has_head = 1;
- const char **pathspec = get_pathspec(prefix, av + 1);
+ const char **paths = get_pathspec(prefix, av + 1);
+ struct pathspec pathspec;
+
+ init_pathspec(&pathspec, paths);
if (read_ref("HEAD", head_sha1))
/* If there is no HEAD, that means it is an initial
@@ -556,7 +559,7 @@ static int do_reupdate(int ac, const char **av,
struct cache_entry *old = NULL;
int save_nr;
- if (ce_stage(ce) || !ce_path_match(ce, pathspec))
+ if (ce_stage(ce) || !ce_path_match(ce, &pathspec))
continue;
if (has_head)
old = read_one_ent(NULL, head_sha1,
@@ -575,6 +578,7 @@ static int do_reupdate(int ac, const char **av,
if (save_nr != active_nr)
goto redo;
}
+ free_pathspec(&pathspec);
return 0;
}
diff --git a/cache.h b/cache.h
index dc54d16..bf50603 100644
--- a/cache.h
+++ b/cache.h
@@ -505,7 +505,7 @@ struct pathspec {
extern int init_pathspec(struct pathspec *,const char **);
extern void free_pathspec(struct pathspec *);
-extern int ce_path_match(const struct cache_entry *ce, const char **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);
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object);
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
diff --git a/diff-lib.c b/diff-lib.c
index 3b809f2..63db7f4 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -89,9 +89,11 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
int silent_on_removed = option & DIFF_SILENT_ON_REMOVED;
unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
? CE_MATCH_RACY_IS_DIRTY : 0);
+ struct pathspec pathspec;
diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");
+ init_pathspec(&pathspec, revs->prune_data);
if (diff_unmerged_stage < 0)
diff_unmerged_stage = 2;
entries = active_nr;
@@ -106,7 +108,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
break;
- if (!ce_path_match(ce, revs->prune_data))
+ if (!ce_path_match(ce, &pathspec))
continue;
if (ce_stage(ce)) {
@@ -218,6 +220,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
ce->name, 0, dirty_submodule);
}
+ free_pathspec(&pathspec);
diffcore_std(&revs->diffopt);
diff_flush(&revs->diffopt);
return 0;
@@ -417,6 +420,7 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o)
struct cache_entry *idx = src[0];
struct cache_entry *tree = src[1];
struct rev_info *revs = o->unpack_data;
+ struct pathspec pathspec;
/*
* Unpack-trees generates a DF/conflict entry if
@@ -427,8 +431,10 @@ static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o)
if (tree == o->df_conflict_entry)
tree = NULL;
- if (ce_path_match(idx ? idx : tree, revs->prune_data))
+ init_pathspec(&pathspec, revs->prune_data);
+ if (ce_path_match(idx ? idx : tree, &pathspec))
do_oneway_diff(o, idx, tree);
+ free_pathspec(&pathspec);
return 0;
}
diff --git a/preload-index.c b/preload-index.c
index e3d0bda..49cb08d 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -35,7 +35,9 @@ static void *preload_thread(void *_data)
struct index_state *index = p->index;
struct cache_entry **cep = index->cache + p->offset;
struct cache_def cache;
+ struct pathspec pathspec;
+ init_pathspec(&pathspec, p->pathspec);
memset(&cache, 0, sizeof(cache));
nr = p->nr;
if (nr + p->offset > index->cache_nr)
@@ -51,7 +53,7 @@ static void *preload_thread(void *_data)
continue;
if (ce_uptodate(ce))
continue;
- if (!ce_path_match(ce, p->pathspec))
+ if (!ce_path_match(ce, &pathspec))
continue;
if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
continue;
@@ -61,6 +63,7 @@ static void *preload_thread(void *_data)
continue;
ce_mark_uptodate(ce);
} while (--nr > 0);
+ free_pathspec(&pathspec);
return NULL;
}
diff --git a/read-cache.c b/read-cache.c
index 1f42473..918a90c 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -683,17 +683,19 @@ int ce_same_name(struct cache_entry *a, struct cache_entry *b)
return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
}
-int ce_path_match(const struct cache_entry *ce, const char **pathspec)
+int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec)
{
const char *match, *name;
+ const char **p;
int len;
- if (!pathspec)
+ if (!pathspec || !pathspec->nr)
return 1;
len = ce_namelen(ce);
name = ce->name;
- while ((match = *pathspec++) != NULL) {
+ p = pathspec->raw;
+ while ((match = *p++) != NULL) {
int matchlen = strlen(match);
if (matchlen > len)
continue;
diff --git a/revision.c b/revision.c
index b2a5867..e77184a 100644
--- a/revision.c
+++ b/revision.c
@@ -951,6 +951,7 @@ static void prepare_show_merge(struct rev_info *revs)
unsigned char sha1[20];
const char **prune = NULL;
int i, prune_num = 1; /* counting terminating NULL */
+ struct pathspec pathspec;
if (get_sha1("HEAD", sha1) || !(head = lookup_commit(sha1)))
die("--merge without HEAD?");
@@ -965,11 +966,12 @@ static void prepare_show_merge(struct rev_info *revs)
if (!active_nr)
read_cache();
+ init_pathspec(&pathspec, revs->prune_data);
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
if (!ce_stage(ce))
continue;
- if (ce_path_match(ce, revs->prune_data)) {
+ if (ce_path_match(ce, &pathspec)) {
prune_num++;
prune = xrealloc(prune, sizeof(*prune) * prune_num);
prune[prune_num-2] = ce->name;
@@ -979,6 +981,7 @@ static void prepare_show_merge(struct rev_info *revs)
ce_same_name(ce, active_cache[i+1]))
i++;
}
+ free_pathspec(&pathspec);
revs->prune_data = prune;
revs->limited = 1;
}
diff --git a/wt-status.c b/wt-status.c
index 54b6b03..70bd378 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -350,14 +350,16 @@ static void wt_status_collect_changes_index(struct wt_status *s)
static void wt_status_collect_changes_initial(struct wt_status *s)
{
+ struct pathspec pathspec;
int i;
+ init_pathspec(&pathspec, s->pathspec);
for (i = 0; i < active_nr; i++) {
struct string_list_item *it;
struct wt_status_change_data *d;
struct cache_entry *ce = active_cache[i];
- if (!ce_path_match(ce, s->pathspec))
+ if (!ce_path_match(ce, &pathspec))
continue;
it = string_list_insert(&s->change, ce->name);
d = it->util;
@@ -372,6 +374,7 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
else
d->index_status = DIFF_STATUS_ADDED;
}
+ free_pathspec(&pathspec);
}
static void wt_status_collect_untracked(struct wt_status *s)
--
1.7.1.rc1.70.g788ca
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/5] ce_path_match: drop prefix matching in favor of match_pathspec
2010-09-19 23:29 [PATCH 0/5] Globbing support in diff family Nguyễn Thái Ngọc Duy
` (3 preceding siblings ...)
2010-09-19 23:29 ` [PATCH 4/5] Convert ce_path_match() to use struct pathspec Nguyễn Thái Ngọc Duy
@ 2010-09-19 23:30 ` Nguyễn Thái Ngọc Duy
4 siblings, 0 replies; 9+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2010-09-19 23:30 UTC (permalink / raw)
To: git; +Cc: Nguyễn Thái Ngọc Duy
ce_path_match() and tree_entry_interesting() are two functions that do
entry filtering when traversing trees. Now that
tree_entry_interesting() understands wildcard, ce_path_match() can
just use match_pathspec() to also understand wildcard.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
read-cache.c | 25 +------------------------
t/t4010-diff-pathspec.sh | 9 +++++++++
2 files changed, 10 insertions(+), 24 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index 918a90c..c67d9e0 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -685,30 +685,7 @@ int ce_same_name(struct cache_entry *a, struct cache_entry *b)
int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec)
{
- const char *match, *name;
- const char **p;
- int len;
-
- if (!pathspec || !pathspec->nr)
- return 1;
-
- len = ce_namelen(ce);
- name = ce->name;
- p = pathspec->raw;
- while ((match = *p++) != NULL) {
- int matchlen = strlen(match);
- if (matchlen > len)
- continue;
- if (memcmp(name, match, matchlen))
- continue;
- if (matchlen && name[matchlen-1] == '/')
- return 1;
- if (name[matchlen] == '/' || !name[matchlen])
- return 1;
- if (!matchlen)
- return 1;
- }
- return 0;
+ return match_pathspec(pathspec->raw, ce->name, ce_namelen(ce), 0, NULL) > 0;
}
/*
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
index 4b120f8..d50fd2d 100755
--- a/t/t4010-diff-pathspec.sh
+++ b/t/t4010-diff-pathspec.sh
@@ -55,6 +55,15 @@ test_expect_success \
'git diff-index --cached $tree -- file0 >current &&
compare_diff_raw current expected'
+cat >expected.template <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+EOF
+test_expect_success 'diff-index with wildcard' '
+ git diff-index --cached $tree -- "*1" >current &&
+ cp expected.template expected &&
+ compare_diff_raw current expected
+'
+
cat >expected <<\EOF
EOF
test_expect_success \
--
1.7.1.rc1.70.g788ca
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/5] pathspec: add tree_recursive_diff parameter
2010-09-19 23:29 ` [PATCH 2/5] pathspec: add tree_recursive_diff parameter Nguyễn Thái Ngọc Duy
@ 2010-09-27 22:20 ` Junio C Hamano
2010-09-28 2:38 ` Nguyen Thai Ngoc Duy
0 siblings, 1 reply; 9+ messages in thread
From: Junio C Hamano @ 2010-09-27 22:20 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy; +Cc: git
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
> When wildcard match is implemented, a full path is needed to do final
> match. What type of diff_tree is performed determines how to treat
> directories:
>
> - If it's recursive diff, directories are just an intermediate step.
> All path must end with a file name. Thus, directories will be
> unconditionally matched.
Hmm, I am not sure what you mean by this. If the pathspec says a/b*/c,
you are in "a" and are deciding if you should descend to its subdirectory,
then you would surely want to be able to say:
(1) Ah, the subdirectory I am looking at is "bar" and it does match "b*".
It might contain "c"; I should descend into it.
(2) Nope, the subdirectory I am looking at is "frotz" and it can never
match "b*", so there is no point recursing into it.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/5] pathspec: add tree_recursive_diff parameter
2010-09-27 22:20 ` Junio C Hamano
@ 2010-09-28 2:38 ` Nguyen Thai Ngoc Duy
2010-09-28 5:28 ` Junio C Hamano
0 siblings, 1 reply; 9+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2010-09-28 2:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
2010/9/28 Junio C Hamano <gitster@pobox.com>:
> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>
>> When wildcard match is implemented, a full path is needed to do final
>> match. What type of diff_tree is performed determines how to treat
>> directories:
>>
>> - If it's recursive diff, directories are just an intermediate step.
>> All path must end with a file name. Thus, directories will be
>> unconditionally matched.
>
> Hmm, I am not sure what you mean by this. If the pathspec says a/b*/c,
> you are in "a" and are deciding if you should descend to its subdirectory,
> then you would surely want to be able to say:
>
> (1) Ah, the subdirectory I am looking at is "bar" and it does match "b*".
> It might contain "c"; I should descend into it.
>
> (2) Nope, the subdirectory I am looking at is "frotz" and it can never
> match "b*", so there is no point recursing into it.
>
I did not go that far, trying to analyse the pattern. When I wrote
"immediate step" I was thinking of "*foo" pattern, which effectively
means descending to any reachable directories because '*' matches
slashes too. I think that's the worst case.
Anyway I did not know that I could borrow some optimizations from
pathspec_matches() in builtin/grep.c.
--
Duy
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/5] pathspec: add tree_recursive_diff parameter
2010-09-28 2:38 ` Nguyen Thai Ngoc Duy
@ 2010-09-28 5:28 ` Junio C Hamano
0 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2010-09-28 5:28 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: git
Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:
> 2010/9/28 Junio C Hamano <gitster@pobox.com>:
>> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>> ...
>>> - If it's recursive diff, directories are just an intermediate step.
>>> All path must end with a file name. Thus, directories will be
>>> unconditionally matched.
>>
>> Hmm, I am not sure what you mean by this. If the pathspec says a/b*/c,
>> you are in "a" and are deciding if you should descend to its subdirectory,
>> then you would surely want to be able to say:
>>
>> (1) Ah, the subdirectory I am looking at is "bar" and it does match "b*".
>> It might contain "c"; I should descend into it.
>>
>> (2) Nope, the subdirectory I am looking at is "frotz" and it can never
>> match "b*", so there is no point recursing into it.
>
> I did not go that far, trying to analyse the pattern. When I wrote
> "immediate step" I was thinking of "*foo" pattern, which effectively
> means descending to any reachable directories because '*' matches
> slashes too. I think that's the worst case.
>
> Anyway I did not know that I could borrow some optimizations from
> pathspec_matches() in builtin/grep.c.
As you noticed, over time we have polished our re-implementations of the
pathspec logic to avoid needlessly descending into subdirectories, and the
one in the grep may be the latest incarnation of it. The logic that uses
the path_simplify structure in dir.c may also offer you some inspirations.
Note that the worst case will fall out as a natural consequence of doing
the fallback in the dumb and simple way, so you do not have to worry too
much about it ;-) I would prefer to see the new, consolidated logic to at
least know the easy optimizations we already have.
Thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-09-28 5:28 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-19 23:29 [PATCH 0/5] Globbing support in diff family Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 1/5] pathspec: mark wildcard pathspecs from the beginning Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 2/5] pathspec: add tree_recursive_diff parameter Nguyễn Thái Ngọc Duy
2010-09-27 22:20 ` Junio C Hamano
2010-09-28 2:38 ` Nguyen Thai Ngoc Duy
2010-09-28 5:28 ` Junio C Hamano
2010-09-19 23:29 ` [PATCH 3/5] tree_entry_interesting: turn to match_pathspec if wildcard is present Nguyễn Thái Ngọc Duy
2010-09-19 23:29 ` [PATCH 4/5] Convert ce_path_match() to use struct pathspec Nguyễn Thái Ngọc Duy
2010-09-19 23:30 ` [PATCH 5/5] ce_path_match: drop prefix matching in favor of match_pathspec Nguyễn Thái Ngọc Duy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).