tree-walk.c: make tree_entry_interesting() take an index

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>

Nguyễn Thái Ngọc Duy committed Nov 18, 2018 at 17:47 UTC 67022e02145b3be774febf38e9dc228ed11e6f25
9 files changed +33 -20
builtin/grep.c
+2 -1
@@ -553,7 +553,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
553
554 if (match != all_entries_interesting) {
555 strbuf_addstr(&name, base->buf + tn_len);
556 - match = tree_entry_interesting(&entry, &name,
556 + match = tree_entry_interesting(repo->index,
557 + &entry, &name,
558 0, pathspec);
559 strbuf_setlen(&name, name_base_len);
560
builtin/merge-tree.c
+1 -1
@@ -346,7 +346,7 @@ static void merge_trees(struct tree_desc t[3], const char *base)
346
347 setup_traverse_info(&info, base);
348 info.fn = threeway_callback;
349 - traverse_trees(3, t, &info);
349 + traverse_trees(&the_index, 3, t, &info);
350 }
351
352 static void *get_tree_descriptor(struct tree_desc *desc, const char *rev)
list-objects.c
+2 -1
@@ -113,7 +113,8 @@ static void process_tree_contents(struct traversal_context *ctx,
113
114 while (tree_entry(&desc, &entry)) {
115 if (match != all_entries_interesting) {
116 - match = tree_entry_interesting(&entry, base, 0,
116 + match = tree_entry_interesting(ctx->revs->repo->index,
117 + &entry, base, 0,
118 &ctx->revs->diffopt.pathspec);
119 if (match == all_entries_not_interesting)
120 break;
revision.c
+1
@@ -1463,6 +1463,7 @@ void repo_init_revisions(struct repository *r,
1463 revs->abbrev = DEFAULT_ABBREV;
1464 revs->ignore_merges = 1;
1465 revs->simplify_history = 1;
1466 + revs->pruning.repo = r;
1467 revs->pruning.flags.recursive = 1;
1468 revs->pruning.flags.quick = 1;
1469 revs->pruning.add_remove = file_add_remove;
tree-diff.c
+2 -1
@@ -299,7 +299,8 @@ static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
299 enum interesting match;
300
301 while (t->size) {
302 - match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec);
302 + match = tree_entry_interesting(opt->repo->index, &t->entry,
303 + base, 0, &opt->pathspec);
304 if (match) {
305 if (match == all_entries_not_interesting)
306 t->size = 0;
tree-walk.c
+14 -8
@@ -365,7 +365,8 @@ static void free_extended_entry(struct tree_desc_x *t)
365 }
366 }
367
368 -static inline int prune_traversal(struct name_entry *e,
368 +static inline int prune_traversal(struct index_state *istate,
369 + struct name_entry *e,
370 struct traverse_info *info,
371 struct strbuf *base,
372 int still_interesting)
@@ -374,10 +375,13 @@ static inline int prune_traversal(struct name_entry *e,
375 return 2;
376 if (still_interesting < 0)
377 return still_interesting;
377 - return tree_entry_interesting(e, base, 0, info->pathspec);
378 + return tree_entry_interesting(istate, e, base,
379 + 0, info->pathspec);
380 }
381
380 -int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
382 +int traverse_trees(struct index_state *istate,
383 + int n, struct tree_desc *t,
384 + struct traverse_info *info)
385 {
386 int error = 0;
387 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)
465 }
466 if (!mask)
467 break;
464 - interesting = prune_traversal(e, info, &base, interesting);
468 + interesting = prune_traversal(istate, e, info, &base, interesting);
469 if (interesting < 0)
470 break;
471 if (interesting) {
@@ -928,7 +932,8 @@ static int match_wildcard_base(const struct pathspec_item *item,
932 * Pre-condition: either baselen == base_offset (i.e. empty path)
933 * or base[baselen-1] == '/' (i.e. with trailing slash).
934 */
931 -static enum interesting do_match(const struct name_entry *entry,
935 +static enum interesting do_match(struct index_state *istate,
936 + const struct name_entry *entry,
937 struct strbuf *base, int base_offset,
938 const struct pathspec *ps,
939 int exclude)
@@ -1090,12 +1095,13 @@ match_wildcards:
1095 * Pre-condition: either baselen == base_offset (i.e. empty path)
1096 * or base[baselen-1] == '/' (i.e. with trailing slash).
1097 */
1093 -enum interesting tree_entry_interesting(const struct name_entry *entry,
1098 +enum interesting tree_entry_interesting(struct index_state *istate,
1099 + const struct name_entry *entry,
1100 struct strbuf *base, int base_offset,
1101 const struct pathspec *ps)
1102 {
1103 enum interesting positive, negative;
1098 - positive = do_match(entry, base, base_offset, ps, 0);
1104 + positive = do_match(istate, entry, base, base_offset, ps, 0);
1105
1106 /*
1107 * case | entry | positive | negative | result
@@ -1132,7 +1138,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
1138 positive <= entry_not_interesting) /* #1, #2, #11, #12 */
1139 return positive;
1140
1135 - negative = do_match(entry, base, base_offset, ps, 1);
1141 + negative = do_match(istate, entry, base, base_offset, ps, 1);
1142
1143 /* #8, #18 */
1144 if (positive == all_entries_interesting &&
tree-walk.h
+6 -4
@@ -1,6 +1,7 @@
1 #ifndef TREE_WALK_H
2 #define TREE_WALK_H
3
4 +struct index_state;
5 struct strbuf;
6
7 struct name_entry {
@@ -48,7 +49,7 @@ void *fill_tree_descriptor(struct tree_desc *desc, const struct object_id *oid);
49
50 struct traverse_info;
51 typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *);
51 -int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info);
52 +int traverse_trees(struct index_state *istate, int n, struct tree_desc *t, struct traverse_info *info);
53
54 enum follow_symlinks_result {
55 FOUND = 0, /* This includes out-of-tree links */
@@ -98,8 +99,9 @@ enum interesting {
99 all_entries_interesting = 2 /* yes, and all subsequent entries will be */
100 };
101
101 -extern enum interesting tree_entry_interesting(const struct name_entry *,
102 - struct strbuf *, int,
103 - const struct pathspec *ps);
102 +enum interesting tree_entry_interesting(struct index_state *istate,
103 + const struct name_entry *,
104 + struct strbuf *, int,
105 + const struct pathspec *ps);
106
107 #endif
tree.c
+2 -1
@@ -78,7 +78,8 @@ static int read_tree_1(struct repository *r,
78
79 while (tree_entry(&desc, &entry)) {
80 if (retval != all_entries_interesting) {
81 - retval = tree_entry_interesting(&entry, base, 0, pathspec);
81 + retval = tree_entry_interesting(r->index, &entry,
82 + base, 0, pathspec);
83 if (retval == all_entries_not_interesting)
84 break;
85 if (retval == entry_not_interesting)
unpack-trees.c
+3 -3
@@ -794,6 +794,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
794 struct name_entry *names,
795 struct traverse_info *info)
796 {
797 + struct unpack_trees_options *o = info->data;
798 int i, ret, bottom;
799 int nr_buf = 0;
800 struct tree_desc t[MAX_UNPACK_TREES];
@@ -804,7 +805,6 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
805
806 nr_entries = all_trees_same_as_cache_tree(n, dirmask, names, info);
807 if (nr_entries > 0) {
807 - struct unpack_trees_options *o = info->data;
808 int pos = index_pos_by_traverse_info(names, info);
809
810 if (!o->merge || df_conflicts)
@@ -863,7 +863,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
863 }
864
865 bottom = switch_cache_bottom(&newinfo);
866 - ret = traverse_trees(n, t, &newinfo);
866 + ret = traverse_trees(o->src_index, n, t, &newinfo);
867 restore_cache_bottom(&newinfo, bottom);
868
869 for (i = 0; i < nr_buf; i++)
@@ -1550,7 +1550,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
1550 }
1551
1552 trace_performance_enter();
1553 - ret = traverse_trees(len, t, &info);
1553 + ret = traverse_trees(o->src_index, len, t, &info);
1554 trace_performance_leave("traverse_trees");
1555 if (ret < 0)
1556 goto return_failed;