From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Elijah Newren <newren@gmail.com>,
Junio C Hamano <gitster@pobox.com>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 4/5] tree_entry_interesting(): remove dependency on struct diff_options
Date: Wed, 8 Sep 2010 01:48:02 +1000 [thread overview]
Message-ID: <1283874483-32017-5-git-send-email-pclouds@gmail.com> (raw)
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
next prev parent reply other threads:[~2010-09-08 1:38 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-07 15:47 [PATCH 0/5] en/object-list-with-pathspec (v3?) Nguyễn Thái Ngọc Duy
2010-09-07 15:47 ` [PATCH 1/5] diff-no-index.c: rename read_directory() to read_dir() Nguyễn Thái Ngọc Duy
2010-09-07 15:48 ` [PATCH 2/5] Add testcases showing how pathspecs are ignored with rev-list --objects Nguyễn Thái Ngọc Duy
2010-09-07 15:48 ` [PATCH 3/5] tree-walk: move tree_entry_interesting() from tree-diff.c Nguyễn Thái Ngọc Duy
2010-09-07 15:48 ` Nguyễn Thái Ngọc Duy [this message]
2010-09-07 15:48 ` [PATCH 5/5] Make rev-list --objects work together with pathspecs Nguyễn Thái Ngọc Duy
2010-09-08 7:47 ` [PATCH 0/5] en/object-list-with-pathspec (v3?) Elijah Newren
2010-09-08 9:58 ` Nguyen Thai Ngoc Duy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1283874483-32017-5-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=newren@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.