Skip to content

Commit ef5fbd3

Browse files
committed
Merge branch 'nd/index-dump-in-json' into pu
* nd/index-dump-in-json: dir.c: dump "UNTR" extension as json cache-tree.c: dump "TREE" extension as json read-cache.c: dump "IEOT" extension as json read-cache.c: dump "EOIE" extension as json resolve-undo.c: dump "REUC" extension as json fsmonitor.c: dump "FSMN" extension as json split-index.c: dump "link" extension as json ls-files: add --json to dump the index
2 parents 824356a + c094f3f commit ef5fbd3

File tree

14 files changed

+376
-27
lines changed

14 files changed

+376
-27
lines changed

Documentation/git-ls-files.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ OPTIONS
6060
--stage::
6161
Show staged contents' mode bits, object name and stage number in the output.
6262

63+
--json::
64+
Dump the entire index content in JSON format. This is for
65+
debugging purposes and the JSON structure may change from time
66+
to time.
67+
6368
--directory::
6469
If a whole directory is classified as "other", show just its
6570
name (with a trailing slash) and not its whole contents.

builtin/ls-files.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "cache.h"
99
#include "repository.h"
1010
#include "config.h"
11+
#include "json-writer.h"
1112
#include "quote.h"
1213
#include "dir.h"
1314
#include "builtin.h"
@@ -31,6 +32,7 @@ static int show_modified;
3132
static int show_killed;
3233
static int show_valid_bit;
3334
static int show_fsmonitor_bit;
35+
static int show_json;
3436
static int line_terminator = '\n';
3537
static int debug_mode;
3638
static int show_eol;
@@ -543,6 +545,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
543545
N_("show staged contents' object name in the output")),
544546
OPT_BOOL('k', "killed", &show_killed,
545547
N_("show files on the filesystem that need to be removed")),
548+
OPT_BOOL(0, "json", &show_json,
549+
N_("dump index content in json format")),
546550
OPT_BIT(0, "directory", &dir.flags,
547551
N_("show 'other' directories' names only"),
548552
DIR_SHOW_OTHER_DIRECTORIES),
@@ -660,8 +664,12 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
660664

661665
/* With no flags, we default to showing the cached files */
662666
if (!(show_stage || show_deleted || show_others || show_unmerged ||
663-
show_killed || show_modified || show_resolve_undo))
667+
show_killed || show_modified || show_resolve_undo || show_json))
664668
show_cached = 1;
669+
if (show_json && (show_stage || show_deleted || show_others ||
670+
show_unmerged || show_killed || show_modified ||
671+
show_cached || show_resolve_undo || with_tree))
672+
die(_("--show-json cannot be used with other --show- options, or --with-tree"));
665673

666674
if (with_tree) {
667675
/*
@@ -673,10 +681,22 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
673681
overlay_tree_on_index(the_repository->index, with_tree, max_prefix);
674682
}
675683

676-
show_files(the_repository, &dir);
677-
678-
if (show_resolve_undo)
679-
show_ru_info(the_repository->index);
684+
if (!show_json) {
685+
show_files(the_repository, &dir);
686+
687+
if (show_resolve_undo)
688+
show_ru_info(the_repository->index);
689+
} else {
690+
struct json_writer jw = JSON_WRITER_INIT;
691+
692+
discard_index(the_repository->index);
693+
the_repository->index->jw = &jw;
694+
if (repo_read_index(the_repository) < 0)
695+
die("index file corrupt");
696+
puts(jw.json.buf);
697+
the_repository->index->jw = NULL;
698+
jw_release(&jw);
699+
}
680700

681701
if (ps_matched) {
682702
int bad;

cache-tree.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "tree.h"
44
#include "tree-walk.h"
55
#include "cache-tree.h"
6+
#include "json-writer.h"
67
#include "object-store.h"
78
#include "replace-object.h"
89
#include "promisor-remote.h"
@@ -493,7 +494,8 @@ void cache_tree_write(struct strbuf *sb, struct cache_tree *root)
493494
write_one(sb, root, "", 0);
494495
}
495496

496-
static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
497+
static struct cache_tree *read_one(const char **buffer, unsigned long *size_p,
498+
struct json_writer *jw)
497499
{
498500
const char *buf = *buffer;
499501
unsigned long size = *size_p;
@@ -547,6 +549,15 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
547549
*buffer, subtree_nr);
548550
#endif
549551

552+
if (jw) {
553+
if (it->entry_count >= 0) {
554+
jw_object_string(jw, "oid", oid_to_hex(&it->oid));
555+
jw_object_intmax(jw, "entry_count", it->entry_count);
556+
} else {
557+
jw_object_null(jw, "oid");
558+
}
559+
jw_object_inline_begin_array(jw, "subdirs");
560+
}
550561
/*
551562
* Just a heuristic -- we do not add directories that often but
552563
* we do not want to have to extend it immediately when we do,
@@ -560,12 +571,18 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
560571
struct cache_tree_sub *subtree;
561572
const char *name = buf;
562573

563-
sub = read_one(&buf, &size);
574+
if (jw) {
575+
jw_array_inline_begin_object(jw);
576+
jw_object_string(jw, "name", name);
577+
}
578+
sub = read_one(&buf, &size, jw);
579+
jw_end_gently(jw);
564580
if (!sub)
565581
goto free_return;
566582
subtree = cache_tree_sub(it, name);
567583
subtree->cache_tree = sub;
568584
}
585+
jw_end_gently(jw);
569586
if (subtree_nr != it->subtree_nr)
570587
die("cache-tree: internal error");
571588
*buffer = buf;
@@ -577,11 +594,25 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
577594
return NULL;
578595
}
579596

580-
struct cache_tree *cache_tree_read(const char *buffer, unsigned long size)
597+
struct cache_tree *cache_tree_read(const char *buffer, unsigned long size,
598+
struct json_writer *jw)
581599
{
600+
struct cache_tree *ret;
601+
602+
if (jw) {
603+
jw_object_inline_begin_object(jw, "cache-tree");
604+
jw_object_intmax(jw, "ext-size", size);
605+
jw_object_inline_begin_object(jw, "root");
606+
}
582607
if (buffer[0])
583-
return NULL; /* not the whole tree */
584-
return read_one(&buffer, &size);
608+
ret = NULL; /* not the whole tree */
609+
else
610+
ret = read_one(&buffer, &size, jw);
611+
if (jw) {
612+
jw_end(jw); /* root */
613+
jw_end(jw); /* cache-tree */
614+
}
615+
return ret;
585616
}
586617

587618
static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path)

cache-tree.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "tree-walk.h"
77

88
struct cache_tree;
9+
struct json_writer;
10+
911
struct cache_tree_sub {
1012
struct cache_tree *cache_tree;
1113
int count; /* internally used by update_one() */
@@ -28,7 +30,8 @@ void cache_tree_invalidate_path(struct index_state *, const char *);
2830
struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *);
2931

3032
void cache_tree_write(struct strbuf *, struct cache_tree *root);
31-
struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
33+
struct cache_tree *cache_tree_read(const char *buffer, unsigned long size,
34+
struct json_writer *jw);
3235

3336
int cache_tree_fully_valid(struct cache_tree *);
3437
int cache_tree_update(struct index_state *, int);

cache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ static inline unsigned int canon_mode(unsigned int mode)
302302
#define UNTRACKED_CHANGED (1 << 7)
303303
#define FSMONITOR_CHANGED (1 << 8)
304304

305+
struct json_writer;
305306
struct split_index;
306307
struct untracked_cache;
307308

@@ -326,6 +327,7 @@ struct index_state {
326327
uint64_t fsmonitor_last_update;
327328
struct ewah_bitmap *fsmonitor_dirty;
328329
struct mem_pool *ce_mem_pool;
330+
struct json_writer *jw;
329331
};
330332

331333
/* Name hashing */

dir.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "varint.h"
2020
#include "ewah/ewok.h"
2121
#include "fsmonitor.h"
22+
#include "json-writer.h"
2223
#include "submodule-config.h"
2324

2425
/*
@@ -2826,7 +2827,42 @@ static void load_oid_stat(struct oid_stat *oid_stat, const unsigned char *data,
28262827
oid_stat->valid = 1;
28272828
}
28282829

2829-
struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz)
2830+
static void jw_object_oid_stat(struct json_writer *jw, const char *key,
2831+
const struct oid_stat *oid_stat)
2832+
{
2833+
jw_object_inline_begin_object(jw, key);
2834+
jw_object_bool(jw, "valid", oid_stat->valid);
2835+
jw_object_string(jw, "oid", oid_to_hex(&oid_stat->oid));
2836+
jw_object_stat_data(jw, "stat", &oid_stat->stat);
2837+
jw_end(jw);
2838+
}
2839+
2840+
static void jw_object_untracked_cache_dir(struct json_writer *jw,
2841+
const struct untracked_cache_dir *ucd)
2842+
{
2843+
int i;
2844+
2845+
jw_object_bool(jw, "valid", ucd->valid);
2846+
jw_object_bool(jw, "check-only", ucd->check_only);
2847+
jw_object_stat_data(jw, "stat", &ucd->stat_data);
2848+
jw_object_string(jw, "exclude-oid", oid_to_hex(&ucd->exclude_oid));
2849+
jw_object_inline_begin_array(jw, "untracked");
2850+
for (i = 0; i < ucd->untracked_nr; i++)
2851+
jw_array_string(jw, ucd->untracked[i]);
2852+
jw_end(jw);
2853+
2854+
jw_object_inline_begin_object(jw, "dirs");
2855+
for (i = 0; i < ucd->dirs_nr; i++) {
2856+
jw_object_inline_begin_object(jw, ucd->dirs[i]->name);
2857+
jw_object_untracked_cache_dir(jw, ucd->dirs[i]);
2858+
jw_end(jw);
2859+
}
2860+
jw_end(jw);
2861+
}
2862+
2863+
struct untracked_cache *read_untracked_extension(const void *data,
2864+
unsigned long sz,
2865+
struct json_writer *jw)
28302866
{
28312867
struct untracked_cache *uc;
28322868
struct read_data rd;
@@ -2864,6 +2900,17 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
28642900
uc->dir_flags = get_be32(next + ouc_offset(dir_flags));
28652901
exclude_per_dir = (const char *)next + exclude_per_dir_offset;
28662902
uc->exclude_per_dir = xstrdup(exclude_per_dir);
2903+
2904+
if (jw) {
2905+
jw_object_inline_begin_object(jw, "untracked-cache");
2906+
jw_object_intmax(jw, "ext-size", sz);
2907+
jw_object_string(jw, "ident", ident);
2908+
jw_object_oid_stat(jw, "info/exclude", &uc->ss_info_exclude);
2909+
jw_object_oid_stat(jw, "excludes-file", &uc->ss_excludes_file);
2910+
jw_object_intmax(jw, "flags", uc->dir_flags);
2911+
jw_object_string(jw, "excludes-per-dir", uc->exclude_per_dir);
2912+
}
2913+
28672914
/* NUL after exclude_per_dir is covered by sizeof(*ouc) */
28682915
next += exclude_per_dir_offset + strlen(exclude_per_dir) + 1;
28692916
if (next >= end)
@@ -2905,6 +2952,12 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
29052952
ewah_each_bit(rd.sha1_valid, read_oid, &rd);
29062953
next = rd.data;
29072954

2955+
if (jw) {
2956+
jw_object_inline_begin_object(jw, "root");
2957+
jw_object_untracked_cache_dir(jw, uc->root);
2958+
jw_end(jw);
2959+
}
2960+
29082961
done:
29092962
free(rd.ucd);
29102963
ewah_free(rd.valid);
@@ -2915,6 +2968,7 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
29152968
free_untracked_cache(uc);
29162969
uc = NULL;
29172970
}
2971+
jw_end_gently(jw);
29182972
return uc;
29192973
}
29202974

dir.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "cache.h"
77
#include "strbuf.h"
88

9+
struct json_writer;
10+
911
struct dir_entry {
1012
unsigned int len;
1113
char name[FLEX_ARRAY]; /* more */
@@ -362,7 +364,7 @@ void untracked_cache_remove_from_index(struct index_state *, const char *);
362364
void untracked_cache_add_to_index(struct index_state *, const char *);
363365

364366
void free_untracked_cache(struct untracked_cache *);
365-
struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz);
367+
struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz, struct json_writer *jw);
366368
void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);
367369
void add_untracked_cache(struct index_state *istate);
368370
void remove_untracked_cache(struct index_state *istate);

fsmonitor.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "dir.h"
44
#include "ewah/ewok.h"
55
#include "fsmonitor.h"
6+
#include "json-writer.h"
67
#include "run-command.h"
78
#include "strbuf.h"
89

@@ -50,6 +51,14 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
5051
}
5152
istate->fsmonitor_dirty = fsmonitor_dirty;
5253

54+
if (istate->jw) {
55+
jw_object_inline_begin_object(istate->jw, "fsmonitor");
56+
jw_object_intmax(istate->jw, "version", hdr_version);
57+
jw_object_intmax(istate->jw, "last-update", istate->fsmonitor_last_update);
58+
jw_object_ewah(istate->jw, "dirty", fsmonitor_dirty);
59+
jw_object_intmax(istate->jw, "ext-size", sz);
60+
jw_end(istate->jw);
61+
}
5362
trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful");
5463
return 0;
5564
}

json-writer.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "cache.h"
2+
#include "ewah/ewok.h"
23
#include "json-writer.h"
34

45
void jw_init(struct json_writer *jw)
@@ -202,6 +203,35 @@ void jw_object_null(struct json_writer *jw, const char *key)
202203
strbuf_addstr(&jw->json, "null");
203204
}
204205

206+
void jw_object_stat_data(struct json_writer *jw, const char *name,
207+
const struct stat_data *sd)
208+
{
209+
jw_object_inline_begin_object(jw, name);
210+
jw_object_intmax(jw, "st_ctime.sec", sd->sd_ctime.sec);
211+
jw_object_intmax(jw, "st_ctime.nsec", sd->sd_ctime.nsec);
212+
jw_object_intmax(jw, "st_mtime.sec", sd->sd_mtime.sec);
213+
jw_object_intmax(jw, "st_mtime.nsec", sd->sd_mtime.nsec);
214+
jw_object_intmax(jw, "st_dev", sd->sd_dev);
215+
jw_object_intmax(jw, "st_ino", sd->sd_ino);
216+
jw_object_intmax(jw, "st_uid", sd->sd_uid);
217+
jw_object_intmax(jw, "st_gid", sd->sd_gid);
218+
jw_object_intmax(jw, "st_size", sd->sd_size);
219+
jw_end(jw);
220+
}
221+
222+
static void dump_ewah_one(size_t pos, void *jw)
223+
{
224+
jw_array_intmax(jw, pos);
225+
}
226+
227+
void jw_object_ewah(struct json_writer *jw, const char *key,
228+
struct ewah_bitmap *ewah)
229+
{
230+
jw_object_inline_begin_array(jw, key);
231+
ewah_each_bit(ewah, dump_ewah_one, jw);
232+
jw_end(jw);
233+
}
234+
205235
static void increase_indent(struct strbuf *sb,
206236
const struct json_writer *jw,
207237
int indent)

0 commit comments

Comments
 (0)