tree-walk.c: make tree_entry_interesting() take an index
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 18 Nov 2018 16:47:57 +0000 (17:47 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 19 Nov 2018 01:50:33 +0000 (10:50 +0900)
In order to support :(attr) when matching pathspec on a tree,
tree_entry_interesting() needs to take an index (because
git_check_attr() needs it). This is the preparation step for it. This
also makes it clearer what index we fall back to when looking up
attributes during an unpack-trees operation: the source index.

This also fixes revs->pruning.repo initialization that should have
been done in 2abf350385 (revision.c: remove implicit dependency on
the_index - 2018-09-21). Without it, skip_uninteresting() will
dereference a NULL pointer through this call chain

get_revision(revs)
get_revision_internal
get_revision_1
try_to_simplify_commit
rev_compare_tree
diff_tree_oid(..., &revs->pruning)
ll_diff_tree_oid
diff_tree_paths
ll_diff_tree
skip_uninteresting

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/grep.c
builtin/merge-tree.c
list-objects.c
revision.c
tree-diff.c
tree-walk.c
tree-walk.h
tree.c
unpack-trees.c
index 71df52a333cbc756b057e93bf3d2affca8157860..64b9167a593caac977ef353fe8082942c64c383d 100644 (file)
@@ -553,7 +553,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 
                if (match != all_entries_interesting) {
                        strbuf_addstr(&name, base->buf + tn_len);
-                       match = tree_entry_interesting(&entry, &name,
+                       match = tree_entry_interesting(repo->index,
+                                                      &entry, &name,
                                                       0, pathspec);
                        strbuf_setlen(&name, name_base_len);
 
index 70f6fc916765c5a5ca67c2dfe72e0480128182e3..4984b7e12e90aab356606e6e7d3e6526f31c8c73 100644 (file)
@@ -346,7 +346,7 @@ static void merge_trees(struct tree_desc t[3], const char *base)
 
        setup_traverse_info(&info, base);
        info.fn = threeway_callback;
-       traverse_trees(3, t, &info);
+       traverse_trees(&the_index, 3, t, &info);
 }
 
 static void *get_tree_descriptor(struct tree_desc *desc, const char *rev)
index c41cc80db5bc86279bcf560109f599a9783b2755..63c395d9c20ef0aed5dee610da3ca3eb120dd6a9 100644 (file)
@@ -113,7 +113,8 @@ static void process_tree_contents(struct traversal_context *ctx,
 
        while (tree_entry(&desc, &entry)) {
                if (match != all_entries_interesting) {
-                       match = tree_entry_interesting(&entry, base, 0,
+                       match = tree_entry_interesting(ctx->revs->repo->index,
+                                                      &entry, base, 0,
                                                       &ctx->revs->diffopt.pathspec);
                        if (match == all_entries_not_interesting)
                                break;
index 13e0519c0241635c0c1fd14a7ff12e9478c70bd4..06708337effb0b2676bf3902d1ed48d82cd82709 100644 (file)
@@ -1463,6 +1463,7 @@ void repo_init_revisions(struct repository *r,
        revs->abbrev = DEFAULT_ABBREV;
        revs->ignore_merges = 1;
        revs->simplify_history = 1;
+       revs->pruning.repo = r;
        revs->pruning.flags.recursive = 1;
        revs->pruning.flags.quick = 1;
        revs->pruning.add_remove = file_add_remove;
index 0e5432461026eff15fe101cf017cd839702e5870..34ee3b13b8f8369de4315f71f0d9ab99b1d42f22 100644 (file)
@@ -299,7 +299,8 @@ static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
        enum interesting match;
 
        while (t->size) {
-               match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec);
+               match = tree_entry_interesting(opt->repo->index, &t->entry,
+                                              base, 0, &opt->pathspec);
                if (match) {
                        if (match == all_entries_not_interesting)
                                t->size = 0;
index 79bafbd1a23c4a9e20ec623c084778904c534be7..517bcdecf9ef2d452958e7b1e0dced5ae99569c0 100644 (file)
@@ -365,7 +365,8 @@ static void free_extended_entry(struct tree_desc_x *t)
        }
 }
 
-static inline int prune_traversal(struct name_entry *e,
+static inline int prune_traversal(struct index_state *istate,
+                                 struct name_entry *e,
                                  struct traverse_info *info,
                                  struct strbuf *base,
                                  int still_interesting)
@@ -374,10 +375,13 @@ static inline int prune_traversal(struct name_entry *e,
                return 2;
        if (still_interesting < 0)
                return still_interesting;
-       return tree_entry_interesting(e, base, 0, info->pathspec);
+       return tree_entry_interesting(istate, e, base,
+                                     0, info->pathspec);
 }
 
-int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
+int traverse_trees(struct index_state *istate,
+                  int n, struct tree_desc *t,
+                  struct traverse_info *info)
 {
        int error = 0;
        struct name_entry *entry = xmalloc(n*sizeof(*entry));
@@ -461,7 +465,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
                }
                if (!mask)
                        break;
-               interesting = prune_traversal(e, info, &base, interesting);
+               interesting = prune_traversal(istate, e, info, &base, interesting);
                if (interesting < 0)
                        break;
                if (interesting) {
@@ -928,7 +932,8 @@ static int match_wildcard_base(const struct pathspec_item *item,
  * Pre-condition: either baselen == base_offset (i.e. empty path)
  * or base[baselen-1] == '/' (i.e. with trailing slash).
  */
-static enum interesting do_match(const struct name_entry *entry,
+static enum interesting do_match(struct index_state *istate,
+                                const struct name_entry *entry,
                                 struct strbuf *base, int base_offset,
                                 const struct pathspec *ps,
                                 int exclude)
@@ -1090,12 +1095,13 @@ static enum interesting do_match(const struct name_entry *entry,
  * Pre-condition: either baselen == base_offset (i.e. empty path)
  * or base[baselen-1] == '/' (i.e. with trailing slash).
  */
-enum interesting tree_entry_interesting(const struct name_entry *entry,
+enum interesting tree_entry_interesting(struct index_state *istate,
+                                       const struct name_entry *entry,
                                        struct strbuf *base, int base_offset,
                                        const struct pathspec *ps)
 {
        enum interesting positive, negative;
-       positive = do_match(entry, base, base_offset, ps, 0);
+       positive = do_match(istate, entry, base, base_offset, ps, 0);
 
        /*
         * case | entry | positive | negative | result
@@ -1132,7 +1138,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
            positive <= entry_not_interesting) /* #1, #2, #11, #12 */
                return positive;
 
-       negative = do_match(entry, base, base_offset, ps, 1);
+       negative = do_match(istate, entry, base, base_offset, ps, 1);
 
        /* #8, #18 */
        if (positive == all_entries_interesting &&
index 196831007e618f808661bf4b7f54030890f48563..eefd26bb6214916f7c451d97710b5ee443e52088 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef TREE_WALK_H
 #define TREE_WALK_H
 
+struct index_state;
 struct strbuf;
 
 struct name_entry {
@@ -48,7 +49,7 @@ void *fill_tree_descriptor(struct tree_desc *desc, const struct object_id *oid);
 
 struct traverse_info;
 typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *);
-int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info);
+int traverse_trees(struct index_state *istate, int n, struct tree_desc *t, struct traverse_info *info);
 
 enum follow_symlinks_result {
        FOUND = 0, /* This includes out-of-tree links */
@@ -98,8 +99,9 @@ enum interesting {
        all_entries_interesting = 2 /* yes, and all subsequent entries will be */
 };
 
-extern enum interesting tree_entry_interesting(const struct name_entry *,
-                                              struct strbuf *, int,
-                                              const struct pathspec *ps);
+enum interesting tree_entry_interesting(struct index_state *istate,
+                                       const struct name_entry *,
+                                       struct strbuf *, int,
+                                       const struct pathspec *ps);
 
 #endif
diff --git a/tree.c b/tree.c
index ecd8c8ac29cc96a12a36270c7c25245149745e74..0b5c84d0d79ff6e598d50c829df47c4dcce7d32c 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -78,7 +78,8 @@ static int read_tree_1(struct repository *r,
 
        while (tree_entry(&desc, &entry)) {
                if (retval != all_entries_interesting) {
-                       retval = tree_entry_interesting(&entry, base, 0, pathspec);
+                       retval = tree_entry_interesting(r->index, &entry,
+                                                       base, 0, pathspec);
                        if (retval == all_entries_not_interesting)
                                break;
                        if (retval == entry_not_interesting)
index 7570df481bf69824e4b163a6c7a15985b72d1326..7f9548e741c9f3d8dda13c32f4ec92fb03294b5f 100644 (file)
@@ -794,6 +794,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
                                    struct name_entry *names,
                                    struct traverse_info *info)
 {
+       struct unpack_trees_options *o = info->data;
        int i, ret, bottom;
        int nr_buf = 0;
        struct tree_desc t[MAX_UNPACK_TREES];
@@ -804,7 +805,6 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
 
        nr_entries = all_trees_same_as_cache_tree(n, dirmask, names, info);
        if (nr_entries > 0) {
-               struct unpack_trees_options *o = info->data;
                int pos = index_pos_by_traverse_info(names, info);
 
                if (!o->merge || df_conflicts)
@@ -863,7 +863,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
        }
 
        bottom = switch_cache_bottom(&newinfo);
-       ret = traverse_trees(n, t, &newinfo);
+       ret = traverse_trees(o->src_index, n, t, &newinfo);
        restore_cache_bottom(&newinfo, bottom);
 
        for (i = 0; i < nr_buf; i++)
@@ -1550,7 +1550,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
                }
 
                trace_performance_enter();
-               ret = traverse_trees(len, t, &info);
+               ret = traverse_trees(o->src_index, len, t, &info);
                trace_performance_leave("traverse_trees");
                if (ret < 0)
                        goto return_failed;