Skip to content

Commit 1b840a5

Browse files
committed
Merge branch 'jc/diff-index-unpack'
* jc/diff-index-unpack: diff-index: pass pathspec down to unpack-trees machinery unpack-trees: allow pruning with pathspec traverse_trees(): allow pruning with pathspec
2 parents 2c46103 + 2f88c19 commit 1b840a5

File tree

5 files changed

+38
-6
lines changed

5 files changed

+38
-6
lines changed

diff-lib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ static int diff_cache(struct rev_info *revs,
468468
opts.unpack_data = revs;
469469
opts.src_index = &the_index;
470470
opts.dst_index = NULL;
471+
opts.pathspec = &revs->diffopt.pathspec;
471472

472473
init_tree_desc(&t, tree->buffer, tree->size);
473474
return unpack_trees(1, &t, &opts);

tree-walk.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,17 +309,37 @@ static void free_extended_entry(struct tree_desc_x *t)
309309
}
310310
}
311311

312+
static inline int prune_traversal(struct name_entry *e,
313+
struct traverse_info *info,
314+
struct strbuf *base,
315+
int still_interesting)
316+
{
317+
if (!info->pathspec || still_interesting == 2)
318+
return 2;
319+
if (still_interesting < 0)
320+
return still_interesting;
321+
return tree_entry_interesting(e, base, 0, info->pathspec);
322+
}
323+
312324
int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
313325
{
314326
int ret = 0;
315327
int error = 0;
316328
struct name_entry *entry = xmalloc(n*sizeof(*entry));
317329
int i;
318330
struct tree_desc_x *tx = xcalloc(n, sizeof(*tx));
331+
struct strbuf base = STRBUF_INIT;
332+
int interesting = 1;
319333

320334
for (i = 0; i < n; i++)
321335
tx[i].d = t[i];
322336

337+
if (info->prev) {
338+
strbuf_grow(&base, info->pathlen);
339+
make_traverse_path(base.buf, info->prev, &info->name);
340+
base.buf[info->pathlen-1] = '/';
341+
strbuf_setlen(&base, info->pathlen);
342+
}
323343
for (;;) {
324344
unsigned long mask, dirmask;
325345
const char *first = NULL;
@@ -376,16 +396,22 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
376396
mask |= 1ul << i;
377397
if (S_ISDIR(entry[i].mode))
378398
dirmask |= 1ul << i;
399+
e = &entry[i];
379400
}
380401
if (!mask)
381402
break;
382-
ret = info->fn(n, mask, dirmask, entry, info);
383-
if (ret < 0) {
384-
error = ret;
385-
if (!info->show_all_errors)
386-
break;
403+
interesting = prune_traversal(e, info, &base, interesting);
404+
if (interesting < 0)
405+
break;
406+
if (interesting) {
407+
ret = info->fn(n, mask, dirmask, entry, info);
408+
if (ret < 0) {
409+
error = ret;
410+
if (!info->show_all_errors)
411+
break;
412+
}
413+
mask &= ret;
387414
}
388-
mask &= ret;
389415
ret = 0;
390416
for (i = 0; i < n; i++)
391417
if (mask & (1ul << i))
@@ -395,6 +421,7 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
395421
for (i = 0; i < n; i++)
396422
free_extended_entry(tx + i);
397423
free(tx);
424+
strbuf_release(&base);
398425
return error;
399426
}
400427

tree-walk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct traverse_info {
4444
struct traverse_info *prev;
4545
struct name_entry name;
4646
int pathlen;
47+
struct pathspec *pathspec;
4748

4849
unsigned long conflicts;
4950
traverse_callback_t fn;

unpack-trees.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
444444

445445
newinfo = *info;
446446
newinfo.prev = info;
447+
newinfo.pathspec = info->pathspec;
447448
newinfo.name = *p;
448449
newinfo.pathlen += tree_entry_len(p->path, p->sha1) + 1;
449450
newinfo.conflicts |= df_conflicts;
@@ -1040,6 +1041,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
10401041
info.fn = unpack_callback;
10411042
info.data = o;
10421043
info.show_all_errors = o->show_all_errors;
1044+
info.pathspec = o->pathspec;
10431045

10441046
if (o->prefix) {
10451047
/*

unpack-trees.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct unpack_trees_options {
5252
const char *prefix;
5353
int cache_bottom;
5454
struct dir_struct *dir;
55+
struct pathspec *pathspec;
5556
merge_fn_t fn;
5657
const char *msgs[NB_UNPACK_TREES_ERROR_TYPES];
5758
/*

0 commit comments

Comments
 (0)