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>
This commit is contained in:
parent
e092073d64
commit
67022e0214
@ -553,7 +553,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
|
|||||||
|
|
||||||
if (match != all_entries_interesting) {
|
if (match != all_entries_interesting) {
|
||||||
strbuf_addstr(&name, base->buf + tn_len);
|
strbuf_addstr(&name, base->buf + tn_len);
|
||||||
match = tree_entry_interesting(&entry, &name,
|
match = tree_entry_interesting(repo->index,
|
||||||
|
&entry, &name,
|
||||||
0, pathspec);
|
0, pathspec);
|
||||||
strbuf_setlen(&name, name_base_len);
|
strbuf_setlen(&name, name_base_len);
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ static void merge_trees(struct tree_desc t[3], const char *base)
|
|||||||
|
|
||||||
setup_traverse_info(&info, base);
|
setup_traverse_info(&info, base);
|
||||||
info.fn = threeway_callback;
|
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)
|
static void *get_tree_descriptor(struct tree_desc *desc, const char *rev)
|
||||||
|
@ -113,7 +113,8 @@ static void process_tree_contents(struct traversal_context *ctx,
|
|||||||
|
|
||||||
while (tree_entry(&desc, &entry)) {
|
while (tree_entry(&desc, &entry)) {
|
||||||
if (match != all_entries_interesting) {
|
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);
|
&ctx->revs->diffopt.pathspec);
|
||||||
if (match == all_entries_not_interesting)
|
if (match == all_entries_not_interesting)
|
||||||
break;
|
break;
|
||||||
|
@ -1463,6 +1463,7 @@ void repo_init_revisions(struct repository *r,
|
|||||||
revs->abbrev = DEFAULT_ABBREV;
|
revs->abbrev = DEFAULT_ABBREV;
|
||||||
revs->ignore_merges = 1;
|
revs->ignore_merges = 1;
|
||||||
revs->simplify_history = 1;
|
revs->simplify_history = 1;
|
||||||
|
revs->pruning.repo = r;
|
||||||
revs->pruning.flags.recursive = 1;
|
revs->pruning.flags.recursive = 1;
|
||||||
revs->pruning.flags.quick = 1;
|
revs->pruning.flags.quick = 1;
|
||||||
revs->pruning.add_remove = file_add_remove;
|
revs->pruning.add_remove = file_add_remove;
|
||||||
|
@ -299,7 +299,8 @@ static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
|
|||||||
enum interesting match;
|
enum interesting match;
|
||||||
|
|
||||||
while (t->size) {
|
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) {
|
||||||
if (match == all_entries_not_interesting)
|
if (match == all_entries_not_interesting)
|
||||||
t->size = 0;
|
t->size = 0;
|
||||||
|
22
tree-walk.c
22
tree-walk.c
@ -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 traverse_info *info,
|
||||||
struct strbuf *base,
|
struct strbuf *base,
|
||||||
int still_interesting)
|
int still_interesting)
|
||||||
@ -374,10 +375,13 @@ static inline int prune_traversal(struct name_entry *e,
|
|||||||
return 2;
|
return 2;
|
||||||
if (still_interesting < 0)
|
if (still_interesting < 0)
|
||||||
return still_interesting;
|
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;
|
int error = 0;
|
||||||
struct name_entry *entry = xmalloc(n*sizeof(*entry));
|
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)
|
if (!mask)
|
||||||
break;
|
break;
|
||||||
interesting = prune_traversal(e, info, &base, interesting);
|
interesting = prune_traversal(istate, e, info, &base, interesting);
|
||||||
if (interesting < 0)
|
if (interesting < 0)
|
||||||
break;
|
break;
|
||||||
if (interesting) {
|
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)
|
* Pre-condition: either baselen == base_offset (i.e. empty path)
|
||||||
* or base[baselen-1] == '/' (i.e. with trailing slash).
|
* 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,
|
struct strbuf *base, int base_offset,
|
||||||
const struct pathspec *ps,
|
const struct pathspec *ps,
|
||||||
int exclude)
|
int exclude)
|
||||||
@ -1090,12 +1095,13 @@ match_wildcards:
|
|||||||
* Pre-condition: either baselen == base_offset (i.e. empty path)
|
* Pre-condition: either baselen == base_offset (i.e. empty path)
|
||||||
* or base[baselen-1] == '/' (i.e. with trailing slash).
|
* 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,
|
struct strbuf *base, int base_offset,
|
||||||
const struct pathspec *ps)
|
const struct pathspec *ps)
|
||||||
{
|
{
|
||||||
enum interesting positive, negative;
|
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
|
* 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 */
|
positive <= entry_not_interesting) /* #1, #2, #11, #12 */
|
||||||
return positive;
|
return positive;
|
||||||
|
|
||||||
negative = do_match(entry, base, base_offset, ps, 1);
|
negative = do_match(istate, entry, base, base_offset, ps, 1);
|
||||||
|
|
||||||
/* #8, #18 */
|
/* #8, #18 */
|
||||||
if (positive == all_entries_interesting &&
|
if (positive == all_entries_interesting &&
|
||||||
|
10
tree-walk.h
10
tree-walk.h
@ -1,6 +1,7 @@
|
|||||||
#ifndef TREE_WALK_H
|
#ifndef TREE_WALK_H
|
||||||
#define TREE_WALK_H
|
#define TREE_WALK_H
|
||||||
|
|
||||||
|
struct index_state;
|
||||||
struct strbuf;
|
struct strbuf;
|
||||||
|
|
||||||
struct name_entry {
|
struct name_entry {
|
||||||
@ -48,7 +49,7 @@ void *fill_tree_descriptor(struct tree_desc *desc, const struct object_id *oid);
|
|||||||
|
|
||||||
struct traverse_info;
|
struct traverse_info;
|
||||||
typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, 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 {
|
enum follow_symlinks_result {
|
||||||
FOUND = 0, /* This includes out-of-tree links */
|
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 */
|
all_entries_interesting = 2 /* yes, and all subsequent entries will be */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum interesting tree_entry_interesting(const struct name_entry *,
|
enum interesting tree_entry_interesting(struct index_state *istate,
|
||||||
struct strbuf *, int,
|
const struct name_entry *,
|
||||||
const struct pathspec *ps);
|
struct strbuf *, int,
|
||||||
|
const struct pathspec *ps);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
3
tree.c
3
tree.c
@ -78,7 +78,8 @@ static int read_tree_1(struct repository *r,
|
|||||||
|
|
||||||
while (tree_entry(&desc, &entry)) {
|
while (tree_entry(&desc, &entry)) {
|
||||||
if (retval != all_entries_interesting) {
|
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)
|
if (retval == all_entries_not_interesting)
|
||||||
break;
|
break;
|
||||||
if (retval == entry_not_interesting)
|
if (retval == entry_not_interesting)
|
||||||
|
@ -794,6 +794,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
|
|||||||
struct name_entry *names,
|
struct name_entry *names,
|
||||||
struct traverse_info *info)
|
struct traverse_info *info)
|
||||||
{
|
{
|
||||||
|
struct unpack_trees_options *o = info->data;
|
||||||
int i, ret, bottom;
|
int i, ret, bottom;
|
||||||
int nr_buf = 0;
|
int nr_buf = 0;
|
||||||
struct tree_desc t[MAX_UNPACK_TREES];
|
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);
|
nr_entries = all_trees_same_as_cache_tree(n, dirmask, names, info);
|
||||||
if (nr_entries > 0) {
|
if (nr_entries > 0) {
|
||||||
struct unpack_trees_options *o = info->data;
|
|
||||||
int pos = index_pos_by_traverse_info(names, info);
|
int pos = index_pos_by_traverse_info(names, info);
|
||||||
|
|
||||||
if (!o->merge || df_conflicts)
|
if (!o->merge || df_conflicts)
|
||||||
@ -863,7 +863,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bottom = switch_cache_bottom(&newinfo);
|
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);
|
restore_cache_bottom(&newinfo, bottom);
|
||||||
|
|
||||||
for (i = 0; i < nr_buf; i++)
|
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();
|
trace_performance_enter();
|
||||||
ret = traverse_trees(len, t, &info);
|
ret = traverse_trees(o->src_index, len, t, &info);
|
||||||
trace_performance_leave("traverse_trees");
|
trace_performance_leave("traverse_trees");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto return_failed;
|
goto return_failed;
|
||||||
|
Loading…
Reference in New Issue
Block a user