git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/5] tree_entry_interesting(): remove dependency on struct diff_options

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Sep 7, 2010, 15:48 UTC
Message-ID
<1283874483-32017-5-git-send-email-pclouds@gmail.com>
In-Reply-To
<1283874483-32017-1-git-send-email-pclouds@gmail.com>

This function can be potentially used in more places than just tree-diff.c. "struct diff_options" does not make much sense outside diff_tree_sha1().

Moreover people seem to be agree that diff machinery should learn proper pathspecs too (i.e. glob support [1] and stuff), not just treating pathspecs as tree prefix.

So instead of using pathspecs in diff_options.{nr_paths,paths,pathlens}, tree_entry_interesting() now uses struct exclude_list.

Struct exclude_list is also added to diff_options with the intention to replace {nr_paths,paths,pathlens} later on. But for now, it's just a temporary field.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 diff.h      |    3 +++
 tree-diff.c |   31 ++++++++++++++++++++++++++++---
 tree-walk.c |   26 +++++++++++---------------
 tree-walk.h |    5 +++--
 4 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/diff.h b/diff.h
index bf2f44d..bd8fe9e 100644
--- a/diff.h
+++ b/diff.h
@@ -5,6 +5,7 @@
 #define DIFF_H
 
 #include "tree-walk.h"
+#include "dir.h"
 
 struct rev_info;
 struct diff_options;
@@ -136,6 +137,7 @@ struct diff_options {
 	int nr_paths;
 	const char **paths;
 	int *pathlens;
+	struct exclude_list el;
 	change_fn_t change;
 	add_remove_fn_t add_remove;
 	diff_format_fn_t format_callback;
@@ -163,6 +165,7 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix);
 extern const char mime_boundary_leader[];
 
 extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
+extern void diff_tree_setup_exclude_list(struct diff_options *);
 extern void diff_tree_release_paths(struct diff_options *);
 extern int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
 		     const char *base, struct diff_options *opt);
diff --git a/tree-diff.c b/tree-diff.c
index c74d0b5..c2951af 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -92,8 +92,7 @@ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_
 		if (all_interesting)
 			show = 1;
 		else {
-			show = tree_entry_interesting(desc, base, baselen,
-						      opt);
+			show = tree_entry_interesting(&desc->entry, base, baselen, &opt->el);
 			if (show == 2)
 				all_interesting = 1;
 		}
@@ -152,7 +151,7 @@ static void skip_uninteresting(struct tree_desc *t, const char *base, int basele
 		if (all_interesting)
 			show = 1;
 		else {
-			show = tree_entry_interesting(t, base, baselen, opt);
+			show = tree_entry_interesting(&t->entry, base, baselen, &opt->el);
 			if (show == 2)
 				all_interesting = 1;
 		}
@@ -167,10 +166,34 @@ static void skip_uninteresting(struct tree_desc *t, const char *base, int basele
 	}
 }
 
+void diff_tree_setup_exclude_list(struct diff_options *opt)
+{
+	int i, size1, size2;
+
+	memset(&opt->el, 0, sizeof(opt->el));
+	opt->el.nr = opt->nr_paths;
+	if (!opt->el.nr)
+		return;
+
+	size1 = opt->el.nr * sizeof(struct exclude *);
+	size2 = opt->el.nr * sizeof(struct exclude);
+	opt->el.excludes = xmalloc(size1+size2);
+	memset(opt->el.excludes, 0, size1+size2);
+	for (i=0; i < opt->el.nr; i++) {
+		struct exclude *exc = ((struct exclude *)((char*)opt->el.excludes+size1))+i;
+		exc->base = opt->paths[i];
+		exc->baselen = opt->pathlens[i];
+		opt->el.excludes[i] = exc;
+	}
+}
+
 int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, struct diff_options *opt)
 {
 	int baselen = strlen(base);
+	struct exclude_list el;
 
+	el = opt->el; /* diff_tree() can be nested, save and restore opt->el later */
+	diff_tree_setup_exclude_list(opt);
 	for (;;) {
 		if (DIFF_OPT_TST(opt, QUICK) &&
 		    DIFF_OPT_TST(opt, HAS_CHANGES))
@@ -204,6 +227,8 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru
 		}
 		die("git diff-tree: internal error");
 	}
+	free(opt->el.excludes);
+	opt->el = el;
 	return 0;
 }
 
diff --git a/tree-walk.c b/tree-walk.c
index bc83fa3..c915218 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -2,7 +2,7 @@
 #include "tree-walk.h"
 #include "unpack-trees.h"
 #include "tree.h"
-#include "diff.h"
+#include "dir.h"
 
 static const char *get_mode(const char *str, unsigned int *modep)
 {
@@ -466,25 +466,21 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
  *  - zero for no
  *  - negative for "no, and no subsequent entries will be either"
  */
-static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt)
+int tree_entry_interesting(const struct name_entry *entry, const char *base, int baselen,
+			   const struct exclude_list *el)
 {
-	const char *path;
-	const unsigned char *sha1;
-	unsigned mode;
 	int i;
 	int pathlen;
 	int never_interesting = -1;
 
-	if (!opt->nr_paths)
+	if (!el->nr)
 		return 1;
 
-	sha1 = tree_entry_extract(desc, &path, &mode);
-
-	pathlen = tree_entry_len(path, sha1);
+	pathlen = tree_entry_len(entry->path, entry->sha1);
 
-	for (i = 0; i < opt->nr_paths; i++) {
-		const char *match = opt->paths[i];
-		int matchlen = opt->pathlens[i];
+	for (i = 0; i < el->nr; i++) {
+		const char *match = el->excludes[i]->base;
+		int matchlen = el->excludes[i]->baselen;
 		int m = -1; /* signals that we haven't called strncmp() */
 
 		if (baselen >= matchlen) {
@@ -522,7 +518,7 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int
 			 * Does match sort strictly earlier than path
 			 * with their common parts?
 			 */
-			m = strncmp(match, path,
+			m = strncmp(match, entry->path,
 				    (matchlen < pathlen) ? matchlen : pathlen);
 			if (m < 0)
 				continue;
@@ -549,7 +545,7 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int
 		if (matchlen > pathlen) {
 			if (match[pathlen] != '/')
 				continue;
-			if (!S_ISDIR(mode))
+			if (!S_ISDIR(entry->mode))
 				continue;
 		}
 
@@ -558,7 +554,7 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int
 			 * we cheated and did not do strncmp(), so we do
 			 * that here.
 			 */
-			m = strncmp(match, path, pathlen);
+			m = strncmp(match, entry->path, pathlen);
 
 		/*
 		 * If common part matched earlier then it is a hit,
diff --git a/tree-walk.h b/tree-walk.h
index 0572721..4b37671 100644
--- a/tree-walk.h
+++ b/tree-walk.h
@@ -57,7 +57,8 @@ static inline int traverse_path_len(const struct traverse_info *info, const stru
 	return info->pathlen + tree_entry_len(n->path, n->sha1);
 }
 
-struct diff_options;
-extern int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt);
+struct exclude_list;
+extern int tree_entry_interesting(const struct name_entry *entry, const char *base, int baselen,
+				  const struct exclude_list *el);
 
 #endif
-- 
1.7.1.rc1.69.g24c2f7
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 5 of 8 in “en/object-list-with-pathspec (v3?)”
  1. 0/5 en/object-list-with-pathspec (v3?)Nguyễn Thái Ngọc Duy, Sep 7, 2010
  2. 1/5 diff-no-index.c: rename read_directory() to read_dir()Nguyễn Thái Ngọc Duy, Sep 7, 2010
  3. 2/5 Add testcases showing how pathspecs are ignored with rev-list --objectsNguyễn Thái Ngọc Duy, Sep 7, 2010
  4. 3/5 tree-walk: move tree_entry_interesting() from tree-diff.cNguyễn Thái Ngọc Duy, Sep 7, 2010
  5. 4/5 tree_entry_interesting(): remove dependency on struct diff_optionsNguyễn Thái Ngọc Duy, Sep 7, 2010
  6. 5/5 Make rev-list --objects work together with pathspecsNguyễn Thái Ngọc Duy, Sep 7, 2010
  7. Elijah NewrenSep 8, 2010
  8. Nguyen Thai Ngoc DuySep 8, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.