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 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).