Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- cache-tree.c | 36 +++++++++++++++++++++++++++++++----- cache-tree.h | 5 ++++- read-cache.c | 2 +- t/t3011-ls-files-json.sh | 4 +++- t/t3011/basic | 20 +++++++++++++++++++- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/cache-tree.c b/cache-tree.c index b13bfaf71e..b6a233307e 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -3,6 +3,7 @@ #include "tree.h" #include "tree-walk.h" #include "cache-tree.h" +#include "json-writer.h" #include "object-store.h" #include "replace-object.h" @@ -492,7 +493,8 @@ void cache_tree_write(struct strbuf *sb, struct cache_tree *root) write_one(sb, root, "", 0); } -static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) +static struct cache_tree *read_one(const char **buffer, unsigned long *size_p, + struct json_writer *jw) { const char *buf = *buffer; unsigned long size = *size_p; @@ -546,6 +548,15 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) *buffer, subtree_nr); #endif + if (jw) { + if (it->entry_count >= 0) { + jw_object_string(jw, "oid", oid_to_hex(&it->oid)); + jw_object_intmax(jw, "entry_count", it->entry_count); + } else { + jw_object_null(jw, "oid"); + } + jw_object_inline_begin_array(jw, "subdirs"); + } /* * Just a heuristic -- we do not add directories that often but * we do not want to have to extend it immediately when we do, @@ -559,12 +570,18 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) struct cache_tree_sub *subtree; const char *name = buf; - sub = read_one(&buf, &size); + if (jw) { + jw_array_inline_begin_object(jw); + jw_object_string(jw, "name", name); + } + sub = read_one(&buf, &size, jw); + jw_end_gently(jw); if (!sub) goto free_return; subtree = cache_tree_sub(it, name); subtree->cache_tree = sub; } + jw_end_gently(jw); if (subtree_nr != it->subtree_nr) die("cache-tree: internal error"); *buffer = buf; @@ -576,11 +593,20 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) return NULL; } -struct cache_tree *cache_tree_read(const char *buffer, unsigned long size) +struct cache_tree *cache_tree_read(const char *buffer, unsigned long size, + struct json_writer *jw) { + struct cache_tree *ret; + + if (jw) { + jw_object_inline_begin_object(jw, "root"); + } if (buffer[0]) - return NULL; /* not the whole tree */ - return read_one(&buffer, &size); + ret = NULL; /* not the whole tree */ + else + ret = read_one(&buffer, &size, jw); + jw_end_gently(jw); + return ret; } static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path) diff --git a/cache-tree.h b/cache-tree.h index 757bbc48bc..fc3c73284b 100644 --- a/cache-tree.h +++ b/cache-tree.h @@ -6,6 +6,8 @@ #include "tree-walk.h" struct cache_tree; +struct json_writer; + struct cache_tree_sub { struct cache_tree *cache_tree; int count; /* internally used by update_one() */ @@ -28,7 +30,8 @@ void cache_tree_invalidate_path(struct index_state *, const char *); struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *); void cache_tree_write(struct strbuf *, struct cache_tree *root); -struct cache_tree *cache_tree_read(const char *buffer, unsigned long size); +struct cache_tree *cache_tree_read(const char *buffer, unsigned long size, + struct json_writer *jw); int cache_tree_fully_valid(struct cache_tree *); int cache_tree_update(struct index_state *, int); diff --git a/read-cache.c b/read-cache.c index 4accd8bb08..d09ce42b9a 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1716,7 +1716,7 @@ static int read_index_extension(struct index_state *istate, switch (CACHE_EXT(ext)) { case CACHE_EXT_TREE: - istate->cache_tree = cache_tree_read(data, sz); + istate->cache_tree = cache_tree_read(data, sz, istate->jw); break; case CACHE_EXT_RESOLVE_UNDO: istate->resolve_undo = resolve_undo_read(data, sz); diff --git a/t/t3011-ls-files-json.sh b/t/t3011-ls-files-json.sh index 97bcd814be..fc313f2c9a 100755 --- a/t/t3011-ls-files-json.sh +++ b/t/t3011-ls-files-json.sh @@ -29,6 +29,8 @@ test_expect_success 'setup' ' echo 2 >sub/two && git add sub/two && + git commit -m first && + echo intent-to-add >ita && git add -N ita && @@ -37,7 +39,7 @@ test_expect_success 'setup' ' strip_string oid ident ' -test_expect_success 'ls-files --json, main entries' ' +test_expect_success 'ls-files --json, main entries and TREE' ' compare_json basic ' diff --git a/t/t3011/basic b/t/t3011/basic index 9436445d90..e27f5be5ff 100644 --- a/t/t3011/basic +++ b/t/t3011/basic @@ -63,5 +63,23 @@ }, "file_offset": <number> } - ] + ], + "extensions": { + "TREE": { + "file_offset": <number>, + "ext_size": <number>, + "root": { + "oid": null, + "subdirs": [ + { + "name": "sub", + "oid": <string>, + "entry_count": 1, + "subdirs": [ + ] + } + ] + } + } + } } -- 2.22.0.rc0.322.g2b0371e29a