| #define USE_THE_REPOSITORY_VARIABLE |
| |
| #include "builtin.h" |
| #include "environment.h" |
| #include "parse-options.h" |
| #include "quote.h" |
| #include "refs.h" |
| #include "strbuf.h" |
| #include "shallow.h" |
| |
| static const char *const repo_usage[] = { |
| "git repo info [--format=(keyvalue|nul)|-z] [<key>...]", |
| NULL |
| }; |
| |
| typedef int get_value_fn(struct repository *repo, struct strbuf *buf); |
| |
| enum output_format { |
| FORMAT_KEYVALUE, |
| FORMAT_NUL_TERMINATED, |
| }; |
| |
| struct field { |
| const char *key; |
| get_value_fn *get_value; |
| }; |
| |
| static int get_layout_bare(struct repository *repo UNUSED, struct strbuf *buf) |
| { |
| strbuf_addstr(buf, is_bare_repository() ? "true" : "false"); |
| return 0; |
| } |
| |
| static int get_layout_shallow(struct repository *repo, struct strbuf *buf) |
| { |
| strbuf_addstr(buf, |
| is_repository_shallow(repo) ? "true" : "false"); |
| return 0; |
| } |
| |
| static int get_objects_format(struct repository *repo, struct strbuf *buf) |
| { |
| strbuf_addstr(buf, repo->hash_algo->name); |
| return 0; |
| } |
| |
| static int get_references_format(struct repository *repo, struct strbuf *buf) |
| { |
| strbuf_addstr(buf, |
| ref_storage_format_to_name(repo->ref_storage_format)); |
| return 0; |
| } |
| |
| /* repo_info_fields keys must be in lexicographical order */ |
| static const struct field repo_info_fields[] = { |
| { "layout.bare", get_layout_bare }, |
| { "layout.shallow", get_layout_shallow }, |
| { "objects.format", get_objects_format}, |
| { "references.format", get_references_format }, |
| }; |
| |
| static int repo_info_fields_cmp(const void *va, const void *vb) |
| { |
| const struct field *a = va; |
| const struct field *b = vb; |
| |
| return strcmp(a->key, b->key); |
| } |
| |
| static get_value_fn *get_value_fn_for_key(const char *key) |
| { |
| const struct field search_key = { key, NULL }; |
| const struct field *found = bsearch(&search_key, repo_info_fields, |
| ARRAY_SIZE(repo_info_fields), |
| sizeof(*found), |
| repo_info_fields_cmp); |
| return found ? found->get_value : NULL; |
| } |
| |
| static int print_fields(int argc, const char **argv, |
| struct repository *repo, |
| enum output_format format) |
| { |
| int ret = 0; |
| struct strbuf valbuf = STRBUF_INIT; |
| struct strbuf quotbuf = STRBUF_INIT; |
| |
| for (int i = 0; i < argc; i++) { |
| get_value_fn *get_value; |
| const char *key = argv[i]; |
| |
| get_value = get_value_fn_for_key(key); |
| |
| if (!get_value) { |
| ret = error(_("key '%s' not found"), key); |
| continue; |
| } |
| |
| strbuf_reset(&valbuf); |
| strbuf_reset("buf); |
| |
| get_value(repo, &valbuf); |
| |
| switch (format) { |
| case FORMAT_KEYVALUE: |
| quote_c_style(valbuf.buf, "buf, NULL, 0); |
| printf("%s=%s\n", key, quotbuf.buf); |
| break; |
| case FORMAT_NUL_TERMINATED: |
| printf("%s\n%s%c", key, valbuf.buf, '\0'); |
| break; |
| default: |
| BUG("not a valid output format: %d", format); |
| } |
| } |
| |
| strbuf_release(&valbuf); |
| strbuf_release("buf); |
| return ret; |
| } |
| |
| static int repo_info(int argc, const char **argv, const char *prefix, |
| struct repository *repo) |
| { |
| const char *format_str = NULL; |
| enum output_format format; |
| int format_nul = 0; |
| struct option options[] = { |
| OPT_STRING(0, "format", &format_str, N_("format"), |
| N_("output format")), |
| OPT_BOOL('z', NULL, &format_nul, N_("alias for --format=nul")), |
| OPT_END() |
| }; |
| |
| argc = parse_options(argc, argv, prefix, options, repo_usage, 0); |
| |
| die_for_incompatible_opt2(!!format_nul, "-z", |
| !!format_str, "--format"); |
| |
| format_str = format_str ? format_str : "keyvalue"; |
| |
| if (format_nul || !strcmp(format_str, "nul")) |
| format = FORMAT_NUL_TERMINATED; |
| else if (!strcmp(format_str, "keyvalue")) |
| format = FORMAT_KEYVALUE; |
| else |
| die(_("invalid format '%s'"), format_str); |
| |
| return print_fields(argc, argv, repo, format); |
| } |
| |
| int cmd_repo(int argc, const char **argv, const char *prefix, |
| struct repository *repo) |
| { |
| parse_opt_subcommand_fn *fn = NULL; |
| struct option options[] = { |
| OPT_SUBCOMMAND("info", &fn, repo_info), |
| OPT_END() |
| }; |
| |
| argc = parse_options(argc, argv, prefix, options, repo_usage, 0); |
| |
| return fn(argc, argv, prefix, repo); |
| } |