* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.