Subject: [PATCH/WIP 08/11] tree-walk: mark useful pathspecs

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Mon, 24 Oct 2011 17:36:13 +1100

Useful pathspecs are those that help decide whether an item is in or
out, as opposed to useless ones whose existence does not change the
results.

Callers are responsible for cleaning before use, or doing anything
after.

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 cache.h     |    1 +
 tree-walk.c |   13 ++++++++++---
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/cache.h b/cache.h
index be07ec7..946d910 100644
--- a/cache.h
+++ b/cache.h
@@ -532,6 +532,7 @@ struct pathspec {
 		const char *match;
 		int len;
 		unsigned int use_wildcard:1;
+		unsigned int useful:1;
 	} *items;
 };
 
diff --git a/tree-walk.c b/tree-walk.c
index 2d9d17a..5e9c522 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -595,11 +595,15 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 	pathlen = tree_entry_len(entry);
 
 	for (i = ps->nr - 1; i >= 0; i--) {
-		const struct pathspec_item *item = ps->items+i;
+		struct pathspec_item *item = ps->items+i;
 		const char *match = item->match;
 		const char *base_str = base->buf + base_offset;
 		int matchlen = item->len;
 
+		/* assume it will be used (which usually means break
+		   the loop and return), reset it otherwise */
+		item->useful = 1;
+
 		if (baselen >= matchlen) {
 			/* If it doesn't match, move along... */
 			if (!match_dir_prefix(base_str, match, matchlen))
@@ -634,12 +638,12 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 					return entry_interesting;
 			}
 
-			continue;
+			goto nouse;
 		}
 
 match_wildcards:
 		if (!item->use_wildcard)
-			continue;
+			goto nouse;
 
 		/*
 		 * Concatenate base and entry->path into one and do
@@ -660,6 +664,9 @@ match_wildcards:
 		 */
 		if (ps->recursive && S_ISDIR(entry->mode))
 			return entry_interesting;
+
+nouse:
+		item->useful = 0;
 	}
 	return never_interesting; /* No matches */
 }
-- 
1.7.3.1.256.g2539c.dirty