ctx->info->path_fn_data);
}
- /* Expand data for children. */
- if (list->type == OBJ_TREE) {
+ /*
+ * Expand tree children, except when the set is directly requested
+ * _and_ we are otherwise filtering out trees.
+ */
+ if (list->type == OBJ_TREE &&
+ (!path_is_for_direct_objects(path) || ctx->info->trees)) {
+ /* Use root path if expanding from tagged/direct trees. */
+ const char *expand_path = !strcmp(path, "/tagged-trees")
+ ? root_path : path;
for (size_t i = 0; i < list->oids.nr; i++) {
ret |= add_tree_entries(ctx,
- path,
+ expand_path,
&list->oids.oid[i]);
}
}
{
struct type_and_oid_list *tags = NULL;
struct type_and_oid_list *tagged_blobs = NULL;
- struct type_and_oid_list *root_tree_list = NULL;
+ struct type_and_oid_list *tagged_trees = NULL;
if (info->tags)
CALLOC_ARRAY(tags, 1);
CALLOC_ARRAY(tagged_blobs, 1);
- root_tree_list = strmap_get(&ctx->paths_to_lists, root_path);
+ CALLOC_ARRAY(tagged_trees, 1);
/*
* Pending objects include:
switch (obj->type) {
case OBJ_TREE:
- if (pending->path) {
- char *path = *pending->path ? xstrfmt("%s/", pending->path)
- : xstrdup("");
+ if (pending->path && *pending->path) {
+ char *path = xstrfmt("%s/", pending->path);
add_path_to_list(ctx, path, OBJ_TREE, &obj->oid, 1);
free(path);
+ } else if (!pending->path || !info->trees) {
+ oid_array_append(&tagged_trees->oids, &obj->oid);
} else {
- /* assume a root tree, such as a lightweight tag. */
- oid_array_append(&root_tree_list->oids, &obj->oid);
+ add_path_to_list(ctx, root_path, OBJ_TREE,
+ &obj->oid, 1);
}
break;
free(tagged_blobs);
}
}
+ if (tagged_trees) {
+ if (tagged_trees->oids.nr) {
+ const char *tagged_tree_path = "/tagged-trees";
+ tagged_trees->type = OBJ_TREE;
+ tagged_trees->maybe_interesting = 1;
+ strmap_put(&ctx->paths_to_lists, tagged_tree_path, tagged_trees);
+ push_to_stack(ctx, tagged_tree_path);
+ } else {
+ oid_array_clear(&tagged_trees->oids);
+ free(tagged_trees);
+ }
+ }
if (tags) {
if (tags->oids.nr) {
const char *tag_path = "/tags";
}
return 1;
+ case LOFC_TREE_DEPTH:
+ if (options->tree_exclude_depth) {
+ error(_("tree:%lu filter not supported by the path-walk API"),
+ options->tree_exclude_depth);
+ return 0;
+ }
+ if (info) {
+ info->trees = 0;
+ info->blobs = 0;
+ list_objects_filter_release(options);
+ }
+ return 1;
+
case LOFC_SPARSE_OID:
if (info) {
struct object_id sparse_oid;
3:tree::$(git rev-parse base^{tree})
3:tree::$(git rev-parse base~1^{tree})
3:tree::$(git rev-parse base~2^{tree})
- 3:tree::$(git rev-parse refs/tags/tree-tag^{})
- 3:tree::$(git rev-parse refs/tags/tree-tag2^{})
4:blob:a:$(git rev-parse base~2:a)
- 5:blob:file2:$(git rev-parse refs/tags/tree-tag2^{}:file2)
- 6:tree:a/:$(git rev-parse base:a)
- 7:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
- 8:blob:child/file:$(git rev-parse refs/tags/tree-tag:child/file)
- 9:tree:left/:$(git rev-parse base:left)
- 9:tree:left/:$(git rev-parse base~2:left)
- 10:blob:left/b:$(git rev-parse base~2:left/b)
- 10:blob:left/b:$(git rev-parse base:left/b)
- 11:tree:right/:$(git rev-parse topic:right)
- 11:tree:right/:$(git rev-parse base~1:right)
- 11:tree:right/:$(git rev-parse base~2:right)
- 12:blob:right/c:$(git rev-parse base~2:right/c)
- 12:blob:right/c:$(git rev-parse topic:right/c)
- 13:blob:right/d:$(git rev-parse base~1:right/d)
+ 5:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag^{})
+ 5:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag2^{})
+ 6:blob:file2:$(git rev-parse refs/tags/tree-tag2^{}:file2)
+ 7:tree:a/:$(git rev-parse base:a)
+ 8:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
+ 9:blob:child/file:$(git rev-parse refs/tags/tree-tag:child/file)
+ 10:tree:left/:$(git rev-parse base:left)
+ 10:tree:left/:$(git rev-parse base~2:left)
+ 11:blob:left/b:$(git rev-parse base~2:left/b)
+ 11:blob:left/b:$(git rev-parse base:left/b)
+ 12:tree:right/:$(git rev-parse topic:right)
+ 12:tree:right/:$(git rev-parse base~1:right)
+ 12:tree:right/:$(git rev-parse base~2:right)
+ 13:blob:right/c:$(git rev-parse base~2:right/c)
+ 13:blob:right/c:$(git rev-parse topic:right/c)
+ 14:blob:right/d:$(git rev-parse base~1:right/d)
blobs:10
commits:4
tags:7
3:tree::$(git rev-parse base^{tree})
3:tree::$(git rev-parse base~1^{tree})
3:tree::$(git rev-parse base~2^{tree})
- 3:tree::$(git rev-parse refs/tags/tree-tag^{})
- 3:tree::$(git rev-parse refs/tags/tree-tag2^{})
- 4:tree:a/:$(git rev-parse base:a)
- 5:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
- 6:tree:left/:$(git rev-parse base:left)
- 6:tree:left/:$(git rev-parse base~2:left)
- 7:tree:right/:$(git rev-parse topic:right)
- 7:tree:right/:$(git rev-parse base~1:right)
- 7:tree:right/:$(git rev-parse base~2:right)
+ 4:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag^{})
+ 4:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag2^{})
+ 5:tree:a/:$(git rev-parse base:a)
+ 6:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
+ 7:tree:left/:$(git rev-parse base:left)
+ 7:tree:left/:$(git rev-parse base~2:left)
+ 8:tree:right/:$(git rev-parse topic:right)
+ 8:tree:right/:$(git rev-parse base~1:right)
+ 8:tree:right/:$(git rev-parse base~2:right)
blobs:2
commits:4
tags:7
3:tree::$(git rev-parse base^{tree})
3:tree::$(git rev-parse base~1^{tree})
3:tree::$(git rev-parse base~2^{tree})
- 3:tree::$(git rev-parse refs/tags/tree-tag^{})
- 3:tree::$(git rev-parse refs/tags/tree-tag2^{})
- 4:tree:a/:$(git rev-parse base:a)
- 5:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
- 6:tree:left/:$(git rev-parse base:left)
- 6:tree:left/:$(git rev-parse base~2:left)
- 7:tree:right/:$(git rev-parse topic:right)
- 7:tree:right/:$(git rev-parse base~1:right)
- 7:tree:right/:$(git rev-parse base~2:right)
+ 4:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag^{})
+ 4:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag2^{})
+ 5:tree:a/:$(git rev-parse base:a)
+ 6:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
+ 7:tree:left/:$(git rev-parse base:left)
+ 7:tree:left/:$(git rev-parse base~2:left)
+ 8:tree:right/:$(git rev-parse topic:right)
+ 8:tree:right/:$(git rev-parse base~1:right)
+ 8:tree:right/:$(git rev-parse base~2:right)
blobs:2
commits:4
tags:7
3:tree::$(git rev-parse base^{tree})
3:tree::$(git rev-parse base~1^{tree})
3:tree::$(git rev-parse base~2^{tree})
- 3:tree::$(git rev-parse refs/tags/tree-tag^{})
- 3:tree::$(git rev-parse refs/tags/tree-tag2^{})
4:blob:a:$(git rev-parse base~2:a)
- 5:tree:a/:$(git rev-parse base:a)
- 6:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
- 7:tree:left/:$(git rev-parse base:left)
- 7:tree:left/:$(git rev-parse base~2:left)
- 8:blob:left/b:$(git rev-parse base~2:left/b)
- 9:tree:right/:$(git rev-parse topic:right)
- 9:tree:right/:$(git rev-parse base~1:right)
- 9:tree:right/:$(git rev-parse base~2:right)
- 10:blob:right/c:$(git rev-parse base~2:right/c)
- 11:blob:right/d:$(git rev-parse base~1:right/d)
+ 5:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag^{})
+ 5:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag2^{})
+ 6:tree:a/:$(git rev-parse base:a)
+ 7:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
+ 8:tree:left/:$(git rev-parse base:left)
+ 8:tree:left/:$(git rev-parse base~2:left)
+ 9:blob:left/b:$(git rev-parse base~2:left/b)
+ 10:tree:right/:$(git rev-parse topic:right)
+ 10:tree:right/:$(git rev-parse base~1:right)
+ 10:tree:right/:$(git rev-parse base~2:right)
+ 11:blob:right/c:$(git rev-parse base~2:right/c)
+ 12:blob:right/d:$(git rev-parse base~1:right/d)
blobs:6
commits:4
tags:7
test_cmp_sorted expect out
'
+test_expect_success 'all, tree:0 filter' '
+ test-tool path-walk --filter=tree:0 -- --all >out &&
+
+ cat >expect <<-EOF &&
+ 0:commit::$(git rev-parse topic)
+ 0:commit::$(git rev-parse base)
+ 0:commit::$(git rev-parse base~1)
+ 0:commit::$(git rev-parse base~2)
+ 1:tag:/tags:$(git rev-parse refs/tags/first)
+ 1:tag:/tags:$(git rev-parse refs/tags/second.1)
+ 1:tag:/tags:$(git rev-parse refs/tags/second.2)
+ 1:tag:/tags:$(git rev-parse refs/tags/third)
+ 1:tag:/tags:$(git rev-parse refs/tags/fourth)
+ 1:tag:/tags:$(git rev-parse refs/tags/tree-tag)
+ 1:tag:/tags:$(git rev-parse refs/tags/blob-tag)
+ 2:blob:/tagged-blobs:$(git rev-parse refs/tags/blob-tag^{})
+ 2:blob:/tagged-blobs:$(git rev-parse refs/tags/blob-tag2^{})
+ 3:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag^{tree})
+ 3:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag2)
+ blobs:2
+ commits:4
+ tags:7
+ trees:2
+ EOF
+
+ test_cmp_sorted expect out
+'
+
+test_expect_success 'topic only, tree:0 filter' '
+ test-tool path-walk --filter=tree:0 -- topic >out &&
+
+ cat >expect <<-EOF &&
+ 0:commit::$(git rev-parse topic)
+ 0:commit::$(git rev-parse base~1)
+ 0:commit::$(git rev-parse base~2)
+ blobs:0
+ commits:3
+ tags:0
+ trees:0
+ EOF
+
+ test_cmp_sorted expect out
+'
+
+test_expect_success 'tree:1 filter is rejected' '
+ test_must_fail test-tool path-walk --filter=tree:1 -- --all 2>err &&
+ test_grep "tree:1 filter not supported by the path-walk API" err
+'
+
test_expect_success 'setup sparse filter blob' '
# Cone-mode patterns: include root, exclude all dirs, include left/
cat >patterns <<-\EOF &&
3:tree::$(git rev-parse base^{tree})
3:tree::$(git rev-parse base~1^{tree})
3:tree::$(git rev-parse base~2^{tree})
- 3:tree::$(git rev-parse refs/tags/tree-tag^{})
- 3:tree::$(git rev-parse refs/tags/tree-tag2^{})
4:blob:a:$(git rev-parse base~2:a)
- 5:blob:file2:$(git rev-parse refs/tags/tree-tag2^{}:file2)
- 6:tree:a/:$(git rev-parse base:a)
- 7:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
- 8:tree:left/:$(git rev-parse base:left)
- 8:tree:left/:$(git rev-parse base~2:left)
- 9:blob:left/b:$(git rev-parse base~2:left/b)
- 9:blob:left/b:$(git rev-parse base:left/b)
- 10:tree:right/:$(git rev-parse topic:right)
- 10:tree:right/:$(git rev-parse base~1:right)
- 10:tree:right/:$(git rev-parse base~2:right)
+ 5:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag^{})
+ 5:tree:/tagged-trees:$(git rev-parse refs/tags/tree-tag2^{})
+ 6:blob:file2:$(git rev-parse refs/tags/tree-tag2^{}:file2)
+ 7:tree:a/:$(git rev-parse base:a)
+ 8:tree:child/:$(git rev-parse refs/tags/tree-tag:child)
+ 9:tree:left/:$(git rev-parse base:left)
+ 9:tree:left/:$(git rev-parse base~2:left)
+ 10:blob:left/b:$(git rev-parse base~2:left/b)
+ 10:blob:left/b:$(git rev-parse base:left/b)
+ 11:tree:right/:$(git rev-parse topic:right)
+ 11:tree:right/:$(git rev-parse base~1:right)
+ 11:tree:right/:$(git rev-parse base~2:right)
blobs:6
commits:4
tags:7